可以调用printStackTrace挂起我的程序吗

时间:2019-03-23 12:25:57

标签: java deadlock stack-trace

我有2个线程在运行。一个用于网络事件,另一个用于程序逻辑。由于需要同步,因此使用Java ReetrantLock类。

网络线程工作流程:
-接收消息
-等待锁(myLock.lock())
-将消息传递到逻辑线程
-释放锁(myLock.unlock())

逻辑线程工作流程:
-运行某些系统
-等待锁(myLock.lock())
-运行2个在try catch块内处理网络消息的系统(我们将此阶段称为 A
-最终释放锁(myLock.unlock)

通过这种配置,程序可以在95%的时间正常运行,但是有时会挂起,因此我启动了VisualVM试图了解问题的根源,然后得到了以下result

您可以看到网络线程被锁定,因为它正在等待逻辑线程释放可重入锁(这是预期的)。但是由于某种原因,逻辑线程被卡在打印stackstrace吗?我无法理解如何从这种情况陷入僵局(陷入阶段 A )。

我也尝试使用JProfiler,并且得到了相同的结果。我应该相信我从这些探查器(stacktrace挂起)中看到的内容吗?

顺便说一下,这里是程序似乎挂起的相关代码:

 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
        }
    }

在冻结时,控制台上也没有堆栈跟踪

编辑:这是来自两个系统中需要与网络线程同步的代码(显然,它们都具有相同的锁):

系统1:

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

系统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
}

0 个答案:

没有答案