Может ли вызов printStackTrace зависать моей программы - PullRequest
1 голос
/ 23 марта 2019

У меня работает 2 темы.Один для сетевого события, другой для логики программы.Так как мне нужна некоторая синхронизация, я использую класс Java ReetrantLock.

Рабочий процесс сетевого потока:
- Получение сообщения
- Ожидание блокировки (myLock.lock ())
- Passсообщение логическому потоку
- снять блокировку (myLock.unlock ())

рабочий процесс логического потока:
- запустить некоторые системы
- дождаться блокировки (myLock.lock ())
- запустить 2 системы, которые обрабатывают сетевые сообщения внутри блока try catch (давайте назовем этот этап A )
- окончательно снять блокировку (myLock.unlock)

При такой конфигурации программа работает нормально в 95% случаев, но иногда она зависает, поэтому я запустил VisualVM, чтобы попытаться понять причину проблемы, и получил следующее result

Как вы видите сетьпоток заблокирован, потому что он ожидает, пока логический поток не снимет блокировку повторного входа (что ожидается).Но по какой-то причине логическая нить застряла при печати стековой трассы?Я не могу понять, как я могу получить тупик из этой ситуации (застрял в фазе A ).

Я также пытался использовать JProfiler и получил те же результаты.Должен ли я верить тому, что вижу от этих профилировщиков (зависание стека)?

Кстати вот соответствующий код, где программа, кажется, зависает:

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