2008-12-05 3 views
4

Я использую java.util.concurrent.ExecutorService, который я получил по телефону Executors.newSingleThreadExecutor(). Этот ExecutorService может иногда останавливать обработку задач, даже если он не был выключен и продолжает принимать новые задачи без исключения исключений. В конце концов, он создает достаточно очереди, которую мое приложение отключает с помощью OutOfMemoryError исключений.Что сделало бы один исполнитель задачи прекратить обработку задач?

Документация, похоже, указывает на то, что этот исполнитель одного потока должен пережить ошибки обработки задачи, при необходимости активируя новый рабочий поток, чтобы заменить тот, который умер. Я что-то упускаю?

ответ

9

Похоже, у вас есть два различных вопроса:

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

2) Любое неперехваченное исключение в потоке задачи может полностью уничтожить поток. Когда это произойдет, ExecutorService запустит новый поток для его замены. Но это не означает, что вы можете игнорировать любую проблему, из-за которой нить умирает в первую очередь! Найдите эти невольные исключения и поймайте их!

Это просто догадка (потому что в вашем сообщении недостаточно информации в вашем сообщении), но я не думаю, что ваша проблема заключается в том, что исполнитель задачи прекращает обработку задач. Я предполагаю, что он просто не обрабатывает задачи так быстро, как вы их создаете. (И тот факт, что ваши задачи иногда умирают преждевременно, вероятно, ортогонален этой проблеме.)

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


Хорошо, вот еще одна возможность, которая звучит возможно на основе ваших комментариев (что все будет работать бесперебойно в течение нескольких часов, пока вдруг приходит к ужасной остановке) ...

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

Вот как я бы диагностировать эту проблему:

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

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

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

Удачи вам!

+0

Хорошие баллы. На данный момент я работаю над углом исключения ... Я не думаю, что это проблема с курсом, по крайней мере, на данный момент. Он будет работать в течение нескольких часов, а задачи будут выполняться быстро и стабильно, пока он внезапно не остановится. – rcalder816 2008-12-05 19:12:28

1

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

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

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

3

Я предполагаю, что ваши задачи будут блокироваться бесконечно, а не умирать. У вас есть доказательства, такие как оператор журнала в конце вашей задачи, подскажите, что ваши задачи успешно завершаются?

Это может быть тупик или взаимодействие с каким-либо внешним процессом, который блокирует.

Смежные вопросы