Почему мой поток останавливается, когда я пытаюсь получить доступ к синхронизированному списку? - PullRequest
1 голос
/ 01 декабря 2009

Почему-то вывод такой:

 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 (). Может быть, это происходит так быстро, что другие методы не могут изменить его?

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

Ответы [ 2 ]

6 голосов
/ 01 декабря 2009

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

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

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

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

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

2 голосов
/ 01 декабря 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...