MultiThreading need Help

Hello,



Iam a noob at Jmonkey. So i read this Tutorials about MultiThreading

http://www.jmonkeyengine.com/wiki/doku.php/standardgame_gamestates_and_multithreading_a_new_way_of_thinking

and

http://www.jmonkeyengine.com/wiki/doku.php/chapter_14_-_multiple_threads



But i dont understand them.

How i can use my own threads? When i start them in MAIN, nothing is changing ?

When i start them in the update() method, he will start 1000s auf threads. But then i see changings at the monitor.

Like this:



protected void update(float interpolation)
{
timer.update(); //update the time to get the framerate
interpolation = timer.getTimePerFrame();
input.update(interpolation);
//Falls ESCAPE gedr

I think you've got that quite wrong ! You are starting a new thread every frame !



You do need to subclass BasicGameState, create a StandardGame instance and attach your GameState to it. Now you will be able to start a thread afterwards.



    public static void main(String[] args) {
        standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);
        standardGame.getSettings().setSamples(0);
        standardGame.start();

        GameState client = new TankGameState();
        GameStateManager.getInstance().attachChild(client);
        client.setActive(true);

        Thread t = ...
        t.start();

        logger.info("TankGameState.main complete");
    }


Hope that helps...

Just a side tip, if you dont# really have to don''t try jme2 and multithreading, it's simpley not designed to support it well. (Still there are some ways to use it for physics, network,sound)

richard_hawkes said:

I think you've got that quite wrong ! You are starting a new thread every frame !

You do need to subclass BasicGameState, create a StandardGame instance and attach your GameState to it. Now you will be able to start a thread afterwards.


   public static void main(String[] args) {
       standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);
       standardGame.getSettings().setSamples(0);
       standardGame.start();

       GameState client = new TankGameState();
       GameStateManager.getInstance().attachChild(client);
       client.setActive(true);

       Thread t = ...
       t.start();

       logger.info("TankGameState.main complete");
   }


Hope that helps...



Hi, first thanks.

I try it.
I think you must explain me, what your class new TankGameState() is? This class extends from GameState?
I try it like this, my class extends GameState, i build the three methods render,update,cleanup. I use in the update()-method the rootNode from the my class Main extends BaseGame.
But it doesnt work. I think its because of the ROOTNODE. My thread is using the rootNode. I dont know, how to handle changings in the RootNode.
Perhaps i dont understand anything and do it all wrong.

Here a little bit code
Class Main extends BaseGame:


public class Main extends BaseGame {
.
.
.
.
private static Node rootNode;

public static Node getRootNode() {
      return rootNode;
   }

   public static void setRootNode(Node rootNode) {
      Main.rootNode = rootNode;
   }
.
.
.
public static void main(String[] args)
{
...
..
..
Main aufbau = new Main();
aufbau.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG,Main.class.getClassLoader().getResource("/home/swalok
/workspace/Copy of AntsSimulator/Images/Ameise.png/"));
aufbau.start(); // Start the program
     
      
}

protected void initGame()
{
....
....
..
GameState futterSuche = new FutterSuche();
GameStateManager.create();
GameStateManager.getInstance().attachChild(futterSuche);   
futterSuche.setActive(true);
         
Thread t1 = new Thread(new FutterSuche());
t1.start();
}


 protected void update(float interpolation)
 {
      timer.update();                        //update the time to get the framerate
      interpolation = timer.getTimePerFrame();
      input.update(interpolation);
      //Falls ESCAPE gedr

Thanks i will try and report!

I think you must explain me, what your class new TankGameState() is? This class extends from GameState?


I'm not the guy to help you with this I'm afraid as my knowledge is not deep enough. Can I suggest you try reading this Wiki again, and follow the example: http://www.jmonkeyengine.com/wiki/doku.php/standardgame_gamestates_and_multithreading_a_new_way_of_thinking again !!

if you dont' really have to don''t try jme2 and multithreading, it's simpley not designed to support it well


I do agree that the GameTaskQueueManager is quite confusing. But I think a solution (which you may wish to use also saberdam) is to have a static queue in the main GL thread class:

public static Queue taskQueue = new ConcurrentLinkedQueue();

I've avoided generics here, but you'll probably want to define what type of message would go in to this queue. Then, from any thread, you can run:

MainThread.playerDetailsQueue.add("JOB=X");

And now in your update(float tpf) method, you poll this queue and action appropriately. This seems to work very sweetly for my Darkstar server interaction where any remote player locations are pushed on to the taskqueue, and the update method polls it (once per frame) and actions as necessary. ConcurrentLinkedQueue works well for me because it's a non-blocking thread-safe queue.

Hope this helps !

Richard

Thanks for your reply.

I try it. And yes i read it really often.

I think the problem is, that the main.thread and thread t1 use the same rootNode at same time.

but i dont know how to change this.

Right, I don't fully understand the translation of your code (German?), but you are extending BaseGame… Don't do that!. Extend GameState, that bit's correct, but you must not get this to implement Runnable. You need to create ANOTHER thread as well, as per my original suggestion:



Your main(String[] args) should look like this:





  public static void main(String[] args) {

       // This bit is the same for you…

       standardGame = new StandardGame("GameControl", StandardGame.GameType.GRAPHICAL, null);

       standardGame.getSettings().setSamples(0);

       standardGame.start();



       // Here you have your GameState

       GameState client = new FutterSuche();

       GameStateManager.getInstance().attachChild(client);

       client.setActive(true);



       // Now you have a separate thread.

       Thread t = new Thread(new SeperateThread());

       t.start();

   }





Is this making sense?



I should point out that I am almost certainly one of the least qualified people to help you here, so you take what I say at your own risk  }:-@

Yeah its german :slight_smile:


I should point out that I am almost certainly one of the least qualified people to help you here, so you take what I say at your own risk  evil


This is no problem. I try many things on my own, but it doesnt help.
Thanks for your help.

But i need a thread of futtersuche() and not a seperate thread. The methods in the class FutterSuche make changings of the Location of many boxes.
This changings are delivered to Main.getRootNode(). So in the Class Main.
If i start a thread in Main.update()(that is wrong, i know) i see the movement of the boxes on the screen. But then i start every frame a new thread, like you say . And that is bullshit.
If i start the thread in  Main--->initGame() or in public static void main(String[] args) i cant see the boxes moving. The screen is freezed. I can fly around but the changings of the location of the boxes dont received.
Hm...i try everything now. I dont know what the problem is.


Thanks Thanks. For your help.
I found the problem.
Dont be angry but the problem was in the run()-method.
When the thread starts, it will do the work and will wait.

public void run ()
   {
      while(true)
      {
      futterSuchen();
      wennGefundenZuFutterLaufen();
      }
   }



so i code it with the while(true)-constallation and my boxes are moving now.

OK, well I will take you back to another of my previous posts on this thread :wink:



What you need is for the separate thread to do the main work, and then add tasks to a work queue in your FutterSuche class. You can use the GameTaskQueue here, but can I suggest you create a more simple Java queue right now in the FutterSuche class. eg:



public static Queue<PlayerLocation> taskQueue = new ConcurrentLinkedQueue<PlayerLocation>();



Now then, your separate thread should add "PlayerLocation" objects (I'm using PlayerLocation as an example) to the queue:



FutterSuche.taskQueue.add(new PlayerLocation(…));



Finally, the FutterSuche.update(float tpf) method should do something like this:





    PlayerLocation pl = taskQueue.poll();



    if (pl != null) {

        // Update a location here :slight_smile:

    }





What this is doing is polling one "message" per frame. It may be that the queue was empty, in which case, carry on with the other update bits. If it has something, then away you go with updating that player. You may wish to empty the queue on each update. I'll leave that decision up to you.



Making sense?

I suggest Vectors or ? extending Vectors, since they are always synchronized.

I suggest Vectors or ? extending Vectors, since they are always synchronized.


Please don't do that ! Without wishing to get in to a lengthy debate, Vectors are synchronized on getting, adding, updating etc. The ConncurrentLinkedQueue is faster because of it's ability to allow polling to occur while other threads may be adding objects.

I had a long argument with a colleague about it making very little difference.... I was wrong ! I work in the financial sector, and the application I'm responsible for handles many thousands of executions a second. If you've got one thread writing to the Vector, and the other one reading, you just don't get the throughput.

Sun in fact incorporated the Concurrent tools in 1.5 that were originally a separate download written by Maged M. Michael and Michael L. Scott. That was about 10 years ago, and I only recently found this out !

Hm time to add another TODO to my project, for later when the main stuff works and it's not 4:30am^^

Thanks for the idea with the QUEUE.

I will try it. Thanks for all your ideas.

Thanks for the idea with the QUEUE. I will try it. Thanks for all your ideas.


Hey, no problem. Do let me know how you get on OK? My approach is non-standard (JME suggests that GameTaskQueueManager), but I'm finding it is more readable, faster and easier to implement using my own queue.

Hm time to add another TODO to my project, for later when the main stuff works and it's not 4:30am


lol, I wouldn't worry too much unless you're needing hardcore throughput. I notice you are mentioning Vectors, and I'm pretty sure concurrency is only for maps and queues right now, not lists.

I'm using a vectors in my networksystem,for recivecache and sendcache …