JMP detect thread lock

Hello folks,

I’m working atm with multithreading, but I’m having some issues with locks and I want to detect where are they. I’m using JMP as found on others topics, but it only shows how many time the lock (monitor state) was kept. I want to know how (even a tip is welcome) to see where on the code the lock is hapenning.

Thanks!

Looks like you’re mixing AWT and jME there? Most probably you try to do something like SwingUtilities.invokeAndWait() in the update loop.

You mean the deadlock?

@normen, no i’m not trying something like it. But I want to know if there is some way to see on profile where are code locks, like when we are sampling memory usage or CPU time.

@FrozenShade, Nop, I’m trying to avoid any lock (monitor) on renderer thread, becouse when they happen, the game keeps lagging even at lower CPU/GPU usage.

Then you should avoid ANY (with an exception) synchronization with other threads. Every lock means a waste of time for ‘realtime’ thread. The perfect situation is when your rendering thread reads messages from synchronized queue and, if it is needed, generates such messages and put them on other synchronized queues. For example - rendering thread is ‘stupid’, it only render, there is another thread which keeps the logic, when something needs to be done on the screen, the ‘logic’ thread sends a proper message to the rendering thread.

2 Likes

And that is what i’m doing (or at least trying), but to send messages to non-renderer thread, I need to use synchronize, which needs a lock (as far as I know).

For instance: I have two threads: The main one for rendering and another one to generate the meshes to be rendered (i’ll call it mesher). On the renderer thread I ask a “render” list from mesher thread and if the list isn’t empty, I render it. To avoid a long lock when asking for the list, I just copy it from mesher and release the lock:

private Iterator<Entry<Vec3, Chunk>> getIterator(HashMap<Vec3, Chunk> map) {
    HashMap<Vec3, Chunk> clone;
    synchronized (map) {
        clone = (HashMap<Vec3, Chunk>) map.clone();
        map.clear();
    }
    return clone.entrySet().iterator();
}

But my question is if there is any way to know, using the JMP, where the “locking” code is being called. If I have just one call to this method, then is easy to know, but if I need to call it from other places (on renderer thread), then how I should know which one is having a long wait (to me, long wait is more then 10ms).

I don’t have a specific answer for your specific question sorry, but maybe you’ll find something interesting in RxJava and/or Akka as I did.
(see this [thread][1])
I personaly found a lot of solutions in RxJava. Coding becomes plumbering : managing the data flows through and between your subsystems.
And this is what you want to do : manage the flows between your mesher and your renderer.
[1]: Multithreading approach for many AI - #30 by normen

1 Like

So, it should be done by creating an message object and by placing it on the Mesher’s queue. mesher.put(message) should have an lock inside.
After that the Mesher take the message from its queue (inside an locked code ofc), generates the meshes, creates the reply message which contains the generated stuff (or its copy, if the Mesher needs to keep them) and put that message on the renderer’s queue (with synchronization ofc).
Then the renderer takes the message from its own queue (synchronized code ofc) and adds the meshes to the scene.

In my game it works very similar. imagine that a player clicks on the item on the ground.

  1. message from renderer to the logic informs about click
  2. the logic decides what to do (to take the object to player’s inventory)
  3. th logic sends an message to renderer which contains the ID of the item to be removed from the scene
  4. renderer reads the message and removes the item from the scene.

On the ‘logic side’ there is an object of Item class which contains the item’s geometry. if there is a need, the logic can send that geometry again to the scene.

3 Likes

What FrozenShade describes is a proper and nice way to play the plumber.
For plumbers RxJava is a bit like the shroom in super mario :smile:

synchronize is bad in your example,

use a ConcurrentHashMap / or similar classes from the concurrent pacakge in java instead. They are often lookless implemented, and archive a way better troughput.

However at the same time I kinda feel that you are overoptimizing, without no game no framerate is worth anything, just saying.

@Empire_Phoenix I’ll give a try on synchronized HashMaps since it is built-in from Java (which means should be more optimal). But I didn’t understood why synchronized is bad on that example, you mean beacouse the overhead of clonning the HashMap to avoid concurrent issues?

@FrozenShade and @guillaumevds, got it, thanks.

Synchronized is the bad thing, no matter if you use locks or synchronized blocks or synchronized maps. Thats where you get your blocking from. People try to tell you that your threads should communicate via queues and not share objects they work on, thats bad threading.

Queues, and ConcurrentHashmap (they are not synchronized hashmaps, they work with more magic inside, i spend several hours understanding them :slight_smile: ) are a better approach. synchronizing needs simplified to flush all cores l1,l2,l3 memorys to main memory. However you usually don’t need that at all.

Indeed I got better results using ConcurrentLinkedQueue as Messaging Queue. Thanks for the tip! :grin: But if I’d a bad multithreading using synchronized on that way, this mean the bellow code is bad also? :sweat:

@Override
public void run() {
    while (!Thread.currentThread().isInterrupted()) {
         boolean c;

         c = processMessages();
         c = unloadChunks() || c;
         c = loadChunks() || c; 
         c = updateChunks() || c;

         synchronized (lock) {
         changed = c;
         if (!changed) {
             try {
                 lock.wait();
             } catch (InterruptedException ex) {
                 return;
             }
         }
    }
}

And when I make some relevant change, I call this method:

private void changeNotify() {
     synchronized (lock) {
        lock.notify();
    }
}

I don’t think using sleep is a good aproach on thead loop, so I tought using this would be better…This is also a bad multithreading strategy? If so, how can I setup my thread loop w/o using sleep (which I think is worse).

Use a blocking queue.

You’d really do yourself a big favor if you became familiar with the java.util.concurrent package and did some reading on proper threading approaches. Some of the smartest threading guys in the world (and indeed input from many threading researches) put lots of effort into those classes.

2 Likes

I’ve read it already. I was so dumb that didn’t tought about it. Actually i’m using 4 queues, one for each state of my object, becouse this I was unable to use a ConcurrentBlockingQueue, but I can marge all those queues in a single one and just switch the action based on state :sweat_smile:

Anyway, thanks!! Today I’ve made really nice updates on my code and learned even more about Multithreading. :grin: