JME3 Threading Model

Apologies for the (hopefully) basic question but I couldn’t find a definitive answer in the tutorials/google etc.



I’ve read through https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading and it recommended using enqueue() to read status from the SimpleApplication which makes sense. What I wasn’t sure about though was whether I also need to do it whenever making any changes to the world state. In other words whether JME uses a similar threading model to Swing or something more robust.



For example I’m doing a simple test application with a swing GUI and a JME3 canvas in order to test the rendering/generation of objects in a controlled environment. When I click a button in the GUI then the Swing thread fires an event which then adds an object into the scene…Do I need to enqueue that or can I just add the object to the scene and let the engine sort out the threading/concurrency issues behind the scenes?



i.e. in the swing thread do I need to do:



[java] public void addCard(final Card card) {

mainApp.enqueue(new Callable<Integer>() {



public Integer call() throws Exception {

int ret = rootNode.attachChild(card.getGeometry());

return ret;

}



});

}[/java]



Or can I just do



[java] public void addCard(final Card card) {

rootNode.attachChild(card.getGeometry());

}



});

}

[/java]



Thanks in advance,

Zarch

P.S. It might be worth adding the answer to the threading page in case anyone else has the same question :slight_smile:

Yeah, the whole point of the Application.enqueue thing is to make mods to the scene graph on the OpenGL thread. Once a node is attached to the scene it is super bad to modify it from another thread.

Ok, thanks. That’s what I suspected when I saw the way the query was done but nothing actually said so outright.



Is there any chance of an “invokeLater” style mechanism as well as the current one (could be enque with a runable instead of a callable)? I know JME will (hopefully) get to my request fast but there is still no sense either locking up the swing thread or bouncing via a third thread in cases like this where I’m not using the return value…

Just don’t call get and you won’t block. That’s the same as calling invokeLater. I really wish the examples minimized the Future.get() thing because I think it confuses people.



Your architecture will be much better if you can be fully asynchronous and minimize use of get()… saving it for those times when it’s critically needed. Just like a more flexible version of Swing’s invokeAndWait() (since in this case you can choose to wait now, wait later, or check the status and never wait)

Read the multithreading doc again, nothing blocks. And as paul pointed out, Callable doesn’t imply thatyou actually use the return value.

Ahh, thanks. Yes you are right - I’d missed the significance of the .get() bit. Years of programming in multi threaded Java and I’ve never had cause to use Callable before (I’ve always used Runable). :o



I’ve added a section to the wiki page explaining. Apologies if I’m being presumptuous (or have made a mistake!):

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading#the_jme3_threading_model

1 Like