[SOLVED] Jme3 Beginner: Using Threads…

normen sorry to get back to this, but should do anything specific to make sure the thread is destroyed after it finishes its task?



It might be from something else but I am realizing that after I close my animation my console is still running (even after the thread has finished its task).



and do occasionally get this error:



[java]Oct 13, 2011 4:24:12 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.util.ConcurrentModificationException

at java.util.AbstractList$Itr.checkForComodification(Unknown Source)[/java]

The executor. Just stop that with the application. e.g.

[java]

@Override

public void destroy(){

super.destroy();

executor.shutdown(); // shutdown() I think it is…

}

[/java]

garnaout said:
normen sorry to get back to this, but should do anything specific to make sure the thread is destroyed after it finishes its task?

It might be from something else but I am realizing that after I close my animation my console is still running (even after the thread has finished its task).

and do occasionally get this error:

[java]Oct 13, 2011 4:24:12 PM com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)[/java]


The part of the stack trace the you left off is the most important bit.

[java]Oct 13, 2011 4:55:17 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.util.ConcurrentModificationException

at java.util.AbstractList$Itr.checkForComodification(Unknown Source)

at java.util.AbstractList$Itr.next(Unknown Source)

at com.jme3.cinematic.Cinematic.initialize(Cinematic.java:188)

at com.jme3.app.state.AppStateManager.update(AppStateManager.java:150)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:252)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:144)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:185)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:218)

at java.lang.Thread.run(Unknown Source)[/java]



where do i implemment the destroy() and should I call it? add it here maybe?



[java]//Get the thread data when its done

if(future.isDone())

{

adapter = (Jme3Adapter) future.get();

future = null;



}[/java]

You add the destroying of the executor in the main application class, its the only one that has a destroy() method to override. Also, it seems you change classes that are used in the scene graph when you get these comodification errors. Do not use the cinematics objects in the scene or attach the spatials there as long as they are processed on another thread!

1 Like

That stack trace indicates that you are either adding events from another event or adding events from another thread (which is much much worse).



At any rate, I wonder why initialize() was being called late in the run of the application. It should have been initialized a long time before that I guess.

I really don’t think I’m adding any except updating the animation timer on the screen. Anyways I added this function and it seems to work fine now. I wonder tho shouldn’t we have shut it down whenever the task was done at [java]if(future.isDone())[/java]

No, there will be other tasks before your application terminates. If you did that, the second bunch of lines will not be processed. Just leave the executor on during the app lifetime, you can use it for other threads too.

I’ve been attempting to get this code working myself. The other thread I am trying to run currently just prints to the terminal, however it doesn’t run. I get an interesting result. SimpleInit ends before I get inside the runnable callm however the code from the second thread doesn’t run.



I’ve stripped everything down so that now I’m just running the TestPhysicsCar example, with the concurrency code in the SimpleInit() method:



[java]

public void simpleInitApp() {



bulletAppState = new BulletAppState();

bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL); //MultiThreading physics https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:bullet_multithreading

stateManager.attach(bulletAppState);



PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());

setupKeys();

buildvehicle();



/** Concurrency and Threading code /



/
* Multithreading: This constructor creates a new executor with a core pool size of 4. /

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(4);



/
* Multithreading: The future that is used to check the execution status /

Future future = null;



/
* Multithreading: The adapter object that performs the long-running task /

RunnableThread adapter = null;





// A self-contained time-intensive task:

Callable<RunnableThread> printStuff = new Callable<RunnableThread>(){

public RunnableThread call() throws Exception

{



// Now continue parsing from where we left of

RunnableThread ad =new RunnableThread();

System.out.println(“Inside Runnable call.”);

//Process the data and pass it back to Jme3Cinematics

return ad; // I shouldn’t return right? <<<<<<<<<<<<<<<<

}

}; // End Callable





System.out.println(“About to try to start callable”);

/
* Separate thread that reads the rest of the file concurrently with the execution */

try

{

System.out.println(“Trying to start callable now”);

//If we have not started a callable yet, do so!

if(adapter == null && future == null)

{

//Thread starts!

future = executor.submit(printStuff);

System.out.println(“Executor starting callable”);



}

//If we have started a callable already, we check the status

else if(future != null)

{

System.out.println(“Callable alredy started”);



//Get the waylist when its done

if(future.isDone())

{

System.out.println(“Future is Done”);



adapter = (RunnableThread) future.get();

future = null;

}

else if(future.isCancelled())

{

System.out.println(“Future Cancelled”);

//Set future to null. Maybe we succeed next time…

future = null;

}



}// end else future !=null

}

catch(Exception e){

e.printStackTrace();

}



if(adapter != null){

System.out.println(“Success!!!”);

}



System.out.println(“Ending SimpleInit…”);



}// end simpleInit

[/java]





The interesting thing is (as I mentioned) that SimpleInit() ends before it gets into the call. Here is the terminal output that might help explain what I mean:



[xml]

… Oct 16, 2011 2:44:39 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (Gui Node)

About to try to start callable

Trying to start callable

Executor starting callable

Ending SimpleInit…

Inside Runnable call.

Oct 16, 2011 2:44:40 PM com.jme3.scene.Node attachChild

INFO: Child (null) attached to this node (DebugShapeNode) …

[/xml]



Also, here is the class I am trying to run. I expect to see the text in the terminal if it runs:



[java] class RunnableThread {



public void main (String[] arg){

// TODO Auto-generated method stub

System.out.println("=================== RunnableThread Code ======================");



}//end main

}//end class[/java]



Also, I’ve tried with the following code as the RunnableThread class with the same results (the code is never run):



[java] class RunnableThread implements Runnable{



@Override

public void run() {

// TODO Auto-generated method stub

// TODO Auto-generated method stub

System.out.println("=================== RunnableThread Code ======================");



} // end run

}//end class[/java]



Any help would be appreciated.

:brainsout: You do all that in simpleInitApp, which is only called once… Look at the logic of the code you copy/pasted there, its meant to be in the update loop where e.g. the isDone() can be checked for multiple times. I really suggest you try to wrap your head around threading and the update loop a bit more before you attempt to implement threading in your application.



Heres a little primer on threading:

http://www.youtube.com/watch?v=_33cKDqRvzs

think I’ve finally got my head around multi-threading as well, and that just video confirmed my suspicions.

I had first put that code in the updateLoop, however, when I did I couldn’t add the Callable to the executor due to scope. (The callable was in the init Loop, and I “try” to add it to the executor in the updateLoop()). I didn’t think to make that global (it was a late night… brain had high latency without much sleep).



I have since made those things global (stupid oversight), and moved the try/catch back to the updateLoop(). When it runs, it claims it successfully runs the call, yet the RunnableThread still doesn’t print anything to the terminal. All I get is the following repeatedly printed to the terminal (once per update):

[xml]About to try to start callable

Trying to start callable now

Callable alredy started

Future is Done

Success!!!

About to try to start callable

Trying to start callable now

Success!!!

About to try to start callable

Trying to start callable now

Success!!![/xml]



I need this separate thread to start once when the game starts and ends when the game ends, hence the attempt putting everything in the Init method.



Update: I just caught that my RunnableThreads class should implement Callable, so the code for that is below, yet it still doesn’t print the message.

[java]import java.util.concurrent.Callable;





class RunnableThread implements Callable<Object>{



@Override

public Object call() throws Exception {

System.out.println("=================== RunnableThread Code ======================");

return null;

}

}//end class[/java]

Ok, I got it to run. I had yet another simple oversight; starting the actual thread in the RunnableThread class. Since I am not returning anything, I really don’t need the callable, I could just do a normal Runnable. The following code runs, just once, during the SimpleInit(). I don’t really need the other stuff in the updateLoop().



[java] class RunnableThread implements Runnable{



RunnableThread() {

new Thread(this).start();

}



public void run() {

System.out.println("=================== RunnableThread Code ======================");



} // end run

}//end class[/java]

I don’ think so. How you know when the processing is finished?

1 Like

Very good point, I just ran into that problem. In fact, I have an infinite loop in the second thread which I only want to end when the jME window is exited. If I just close the jME window, that thread stays alive until I kill it manually.



The way the program will likely work is as a launch window with settings, once the settings are set, the user clicks the “OK” button and the jME game runs along with this other thread. Once the jME window is closed, then the other threads should end immediately.

Again, try and get your thinking patterns straight here. The code on the thread may never define the actual logic flow of your application, only by the fact that it finished some processing. Theres one thread, the main uber-thread, which repeatedly calls the update method of your application. That is the logic loop where you do all of your decisions.

I don’t think I understand what you mean. What I am trying to do here involves having a TCP connection that must output a status update at a user-specified time. The status info is based on some calculations done in the updateLoop() and saved to semaphores or synchronized blocks, however. I also plan to drive a vehicle in a similar way, a TCP connection will receive a message from a user, then update a synchronized value for setting steering direction and turning on the vehicle motor. The update loop will check these values to update the actual vehicleControl info. I don’t see how the communication and the set timings can be done within the update loop.



Additionally, I found a way to stop the Runnable by creating a stop() method in the Runnable that clears the value set in the run() method’s while loop.



In SimpleInit() I have “executor.execute(runThread); " where runThread is a globally declared instance of RunnableThread.



I then added the following Override method in the jME Game:

[java]@Override

public void destroy(){

super.destroy();

executor.shutdown(); //Shut down executor

runThread.stop(); //stop the runnableThread

}

[/java]



Here is the RunnableThread with the new stop() method:



[java]class RunnableThread implements Runnable {



RunnableThread() {

//new Thread(this).start();

}

private volatile Thread flag;



public void stop() {

flag = null;

}



public void run() {

Thread thisThread = Thread.currentThread();

flag = thisThread;

while (flag == thisThread) {

System.out.println(”=================== RunnableThread Code ======================");

try {

//wait(1000);

Thread.sleep(1000);

} catch (InterruptedException ex) {

Logger.getLogger(RunnableThread.class.getName()).log(Level.SEVERE, null, ex);

}



}// end while

System.out.println(“Finished!”);

} // end run

}//end class[/java]

:brainsout:

From the monkey without a brain graphic I take it that this isn’t good…

pspeed, sorry to get back to this:


That stack trace indicates that you are either adding events from another event or adding events from another thread (which is much much worse).


I think I am as thread 2 parses the 2nd chunk of the trace file and executes on the fly. Is that what you meant? If so, what are my other options?