BlackBerry — поток не отвечает

#java #multithreading #blackberry #invoke #invokelater

#java #многопоточность #ежевика #вызвать #invokelater

Вопрос:

Я сожалею, что этот вопрос немного расплывчатый, но я не смог получить никакой полезной информации из debugging.

У меня есть поток, который я вызываю с помощью new Thread().Запустите, затем он будет выполняться в течение короткого времени, и я получаю это сообщение:

Неперехваченное исключение: приложение «my app name (201)» не отвечает; процесс завершен

Теперь, что расстраивает, я могу запустить тот же процесс, но без потока, который затем блокирует мое приложение, но я вижу из своей консоли Eclipse, что он работает без ошибок. Итак, я знаю, что это не ошибка с функциями, которые я использую в потоке.

Я подумал, что, возможно, проблема может заключаться в том, что я использую функцию «invokeLater» для обновления моего графического интерфейса с прогрессией потоков, я довольно усердно рассылаю спам и боюсь, что это разрушит мой поток.

Есть предложения?

Чтобы расширить мой пост, проблема возникла из-за того, что я часто вызывал этот код из другого потока:-

  invokeLater(new Runnable() 
        {
            public void run() 
            {
                _output.setText(_output.getText()   "n"   msg);
            }
        });
  

Это создавало очередь, которая быстро привела к сбою моего приложения.

Моим решением было использовать поток событий, добавив этот код в мою функцию:-

    synchronized(Application.getEventLock()) {
       _output.setText("new text "   System.currentTimeMillis());
   }
  

Комментарии:

1. Возможно, вы захотите опубликовать некоторый код, чтобы показать, что делает ваш поток.

2. Вы уверены, что используете invokeLater (), а не invokeAndWait()? Я сталкивался с этим раньше, когда использовал автозаполнение. Также я согласен с NGAC, некоторый код был бы невероятно полезен.

3. Основываясь на вашей правке, я хочу отметить, что ваш исходный код квадратичен, в то время как код замены линейный, поэтому вы не можете сравнивать их по производительности.

Ответ №1:

Вы совершенно правы:

Я подумал, что, возможно, проблема может заключаться в том, что я использую функцию «invokeLater» для обновления моего графического интерфейса с прогрессией потоков, я довольно усердно рассылаю спам и боюсь, что это разрушит мой поток.

Вызов invokeLater возвращается немедленно, и работают очереди для выполнения потока пользовательского интерфейса. Проблема в том, что если эта очередь станет слишком большой, ОС убьет ваше приложение, предполагая, что пользовательский интерфейс увяз до такой степени, что он не обслуживает очередь.

Решение, которое я использовал, чтобы обойти это в прошлом, заключается в разделении работы, отправляемой в поток пользовательского интерфейса. Создайте какой-нибудь объект-накопитель, логический флаг и блокировку. Затем рабочий поток перехватывает блокировку и добавляет работу накопителю. Логический флаг указывает, планируется ли в будущем, что рабочий код пользовательского интерфейса очистит накопитель. Если нет, запланируйте обновление кода пользовательского интерфейса.

В коде обновления пользовательского интерфейса вы снимаете блокировку и перемещаете данные из накопителя как можно быстрее, и помечаете логическое значение как false, чтобы показать, что больше не запланировано, чтобы работник пользовательского интерфейса опорожнял накопитель.

Комментарии:

1. Спасибо, похоже, это проблема, я начну работать над тем, что вы предложили сейчас.

Ответ №2:

Если вы синхронизированы с каким-либо объектом в потоке, выполняя что-то, отнимающее много времени, и если ваш поток пользовательского интерфейса попытается выполнить синхронизацию с тем же объектом, он будет заблокирован до тех пор, пока блокировка не будет снята.

Ответ №3:

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