Почему мой поток останавливается, когда я пытаюсь получить доступ к синхронизированному списку?

StackOverflow https://stackoverflow.com/questions/1824768

  •  22-07-2019
  •  | 
  •  

Вопрос

По какой-то причине вывод этого:

 public void msgNeedParts() {
    // Blabla...
    System.out.println(name + ": Try to print 'tasks'...");
    synchronized(tasks) {
        System.out.println(name + ": Tasks--" + tasks);
        System.out.println(name + ": Did I manage to print it?");
        tasks.add(new BinToDump(feeder, binNum));
    }
    stateChanged();
 }

Просто распечатывает «GantryAgent:Попробуйте напечатать «задачи...», но не одно из следующих сообщений.Я предполагаю, что поток каким-то образом «застревает» при попытке доступа к «задачам» синхронизированного списка, но я не знаю, почему это происходит.

«задачи» были объявлены и инициализированы следующим образом:

private List<BinToDump> tasks = 
    Collections.synchronizedList(new ArrayList<BinToDump>());

Может ли кто-нибудь указать, чего мне не хватает?

Ах!Я подозреваю, что у меня есть виновник:

    /* If nothing left to do, return to original position. */

    synchronized (tasks) {

        if (tasks.isEmpty()) {

            doReturnToOriginalPos();

        }

    }

В моем планировщике (это конструкция агента) я проверяю, пуста ли «задача», затем вызываю doReturnToOriginalPos().Может быть, это просто происходит снова и снова так быстро, что другие методы не имеют возможности изменить это?

Это действительно была проблема!В моем планировщике он вызывался так быстро, что ничто другое не могло получить доступ к «задачам».Спасибо всем за помощь!

Это было полезно?

Решение

Что-то имеет блокировку задач.В зависимости от типа приложения вы сможете получить полный дамп системы, но метод может быть разным.Например, я думаю, что CTRL-Break на большинстве серверов приложений на базе Windows сделает то же самое, и я думаю, что отправка SIGQUIT в Linux сделает то же самое.

Получив дамп стека, вы можете просмотреть его и попытаться выяснить, какой еще поток заблокировал этот объект.

Вы также можете использовать ВисуалВМ чтобы получить дамп стека, для той же конечной цели:

Вы можете использовать Java VisualVM, чтобы взять свалку потока (трассировка стека), пока работает локальное приложение.Принятие свалки резьбы не останавливает приложение.Когда вы печатаете дистанцию ​​потока, вы получаете распечатку стека потоков, который включает в себя состояния потока для потоков Java.

Когда вы печатаете дамп потока в Java VisualVM, инструмент печатает трассировку стека активных потоков приложения.Использование Java VisualVM для получения дампа потока может быть очень удобным в тех случаях, когда у вас нет командной консоли для приложения.Вы можете использовать трассировку стека, чтобы помочь диагностировать ряд вопросов, таких как тупики или когда висит приложение.

Другие советы

Возможно ли, что другой поток удерживает блокировку синхронизации tasks?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top