App lags when creating more than 5 threads

I’m using JMonkey for building an agent-based simulation. I used ExecutorService to pool created threads

[java]private ExecutorService service = Executors.newFixedThreadPool(100);[/java]

and then in my SimpleInitApp()function, I created 5 agents which implement Runnable. The constructPlayer method creates the graphical representation(a box) inside the window

[java]for (int i = 0 ; i < 5 ; i++){
agent = new SimmalAgent();
agent.constructPlayer(5+r.nextInt(10),5+r.nextInt(10));
service.execute(agent);
}[/java]

inside my agent, the overrided run method is like this. Basically, i just move the agent by x and z vector

[java]@Override
public void run() {
while(!SimmalConstant.paused){
translationValue.x = 2f;
translationValue.z = 2f;
}
}[/java]

When I created 5 agents, it runs smoothly. The problem is when there are more than 5 agents created, its FPS dropped to the point it’s not playable.

How to fix this? I haven’t used the JME’s multithreading using ScheduledThreadPoolExecutor because I don’t know how to use it.

You allow 100 threads to run, all of them are not waiting for io, but are cpu heavy, that measn on a typical 4core jme only have 1/6 of the availalbe power, this is bad behaviour. Limit your Executor accordingly so, that it does not bloa thte threadpool or use a different more game friendly pattern to code your agents.

All of your threads are just spinning constantly in a while loop repeating the same thing over and over??? :o

Learning by doing is not an option with concurrent programming. You don’t get instant feedback if you do something wrong, you get a bug that may or may not show depending on timing. I have seen concurrency bugs showing up after speeding up a task, because then the unsafe operation would fall into the same time slot as another task doing a parallel update. I have seen concurrency bugs that would show up only with specific compilers, or only before (or only after) JIT did it’s runtime optimization, because all these things influence timing.

You really need to read up on the issues.
Lars Vogel’s tutorial is a good bird’s eye view of what’s there out of the box:
http://www.vogella.com/articles/JavaConcurrency/article.html
A more JME-centric introduction is here: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:multithreading

Also, zarch is 100% on spot. You don’t want to have your agents spin in a busy loop, you definitely want them to do some fixed task and go to sleep until something changed that requires them to recalculate.
They might also want to wake up for updating the scene graph. The right way to do that would require some kind of rendezvous with the render loop; I suppose the best way to do that is mentioned in the JME multithreading docs, too.

Sorry, I just got my internet connection back this time. @zarch is right, I forgot to add Thread.sleep(long mills)in my threads. Now it’s working seamless with 100 threads.

@zarch, @toolforger, The translationValue in my thread is just a test to check whether the agent is actually running by itself or not. hahah

Once again THX for the helps

I think what happened is that the agent threads starved the render thread for CPU.
Give the render threads a lower priority and you’ll have a stable framerate. At worst, the agents can saturate the CPU to 100%, but they can’t prevent the render from happening anymore.

I’d still be a bit cautious about your design. Spinning threads in loops (even with a sleep) tends to suggest that a better approach could be taken.

1 Like