1

I have 2 threads running. One for network event, the other one for the program logic. Since I need some synchronization, I use the Java ReetrantLock class.

Network thread workflow:
- Receive a message
- Wait for the lock (myLock.lock())
- Pass the message to the logic thread
- Release the lock (myLock.unlock())

Logic thread workflow:
- Run some systems
- Wait for the lock (myLock.lock())
- Run 2 systems that process the network messages inside a try catch block (lets call this phase A)
- Finally release the lock (myLock.unlock)

With this configuration the program run fine 95% of the time but sometime it hangs so I launched VisualVM to try to understand to root of the problem and I got the following result

As you can see the network thread is locked because it is waiting for the logic thread to release the reentrant lock (which is expected). But for some reason the logic thread is stuck at printing a stackstrace ? I cannot understand how I can get a deadlock from this situation (stuck in phase A).

I also tried to use JProfiler and I got the same results. Should I believe what I'm seeing from these profiler (stacktrace hanging) ?

By the way here is the relevant code where the program seems to hang :

 public void handle(EntityDeletionMessage message) {
        try {
            Entity toRemove = mapGameState.getEntityById(message.getEntityId());
            mapGameState.removeEntity(toRemove);
        } catch (EntityNotFoundException e) {
            e.printStackTrace(); // From my understanding it freeze here
        }
    }

Also I get no stacktrace on the console when it freeze

Edit: Here is the code from the 2 systems that need to be sync with the network thread (obviously they both sare the same lock):

System 1:

public void update(float deltaTime) {
        lock.lock(); // It will be unlocked in the second system.
        // process some network messages.
}

System 2:

public void update(float deltaTime) {

        while (networkMessages.size > 0) {
            NetworkMessage message = networkMessages.removeFirst();

            MessageHandler handler = messageHandlerManager.getHandler(message.getClass());
            if (handler == null) {
                Gdx.app.error("NetworkMessagesManagerSystem", "No handler for the message: " + message.getClass());
                continue;
            }
            try {
                handler.handle(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        lock.unlock(); // It was locked in the system 1
}
Django
  • 110
  • 7
  • I could imagine that you do not release the lock if the program invokes the `catch`-block. Could you please post the relevant piece of code for further analysis? – embie27 Mar 23 '19 at 12:45

0 Answers0