Java странное завершение потока - PullRequest
1 голос
/ 24 марта 2011

У меня работает система с несколькими потоками - мой основной поток просто проверяет, есть ли задания, которые нужно выполнить, и если они есть, он вызывает подпотоки (notifyAll()), которые будут его выполнять.После этого подпотоки просто wait() пока не появятся новые задачи.

На самом деле, система потоков работает надежно, но после более длительного времени выполнения (3-5 ч) некоторые подпотоки простоумереть без предупреждения или ошибки.Они просто выходят один за другим - но опять же только с временным интервалом 2-х часов.Я использовал jconsole, чтобы проверить это явление, какие потоки работают и как они просто исчезают.

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

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

Я был бы очень благодарен за вашу помощь!

PS Все потоки не определены как демоны, а основной поток просто отлично работает!

edit

Спасибо за ваши ответы, но я фактически использую этот цикл.

public void addTask (Task in_task) throws InterruptedException {
        synchronized (tasks) {
              while (tasks.size() == MAXIMUM_NUMBER_OF_TASKS) {
                   tasks.wait();
              }
              tasks.offer(in_task);
              tasks.notifyAll();
        }
}

Я использую этот цикл, так что будет выполнено только определенное количество задач.

Ответы [ 4 ]

5 голосов
/ 24 марта 2011

Документация для Object.wait () гласит:

Как и в версии с одним аргументом, возможны прерывания и ложные пробуждения, и этот метод всегда должен использоваться в цикле:

 synchronized (obj) {
     while (<condition does not hold>)
         obj.wait();
     ... // Perform action appropriate to condition
 }

Может быть, вы не последовали этому совету и получили ложное пробуждение или прерывание?

2 голосов
/ 24 марта 2011

Вместо написания собственного решения для выполнения многопоточных задач вы можете использовать java.util.concurrent.ThreadPoolExecutor.Это, вероятно, будет хорошей идеей, независимо от того, сможете ли вы исправить эту ошибку или нет.

1 голос
/ 24 марта 2011

Я рекомендую использовать один из Executors для управления своими задачами.Есть меньше шансов, что вы потеряете возможную ошибку или исключение в одной из ваших подпотоков, поэтому это должно помочь вам отладить вашу программу.Любое исключение, которое происходит в подпотоке, будет сохранено внутри объекта Future и переброшено как ExecutionException при вызове Future#get().

List<Future<Void>> taskResults = new ArrayList<Future<Void>>();
ExecutorService es = Executors.newFixedThreadPool(NUMBER_OF_THREADS);

while(!finished){
  //say you wait (blocking) for a new task here
  Callable<Void> task = getNextTask();

  //put the task into the pool
  Future<Void> result = es.submit(task);
  taskResults.add(result);
}

//3 hours later, set `finished` to true

//at the end check that no exceptions were thrown
for(Future<Void> result : taskResults){
  try{
    result.get();
  }catch(ExecutionException e){
    //there was an error
    e.getCause().printStackTrace();
  }catch(InterruptedException e){
    //irrelevant
  }
}

В общем, вещи в java.util.concurrentпомогает писать гораздо более надежные многопоточные приложения, не прибегая к Object#wait() и другим примитивам параллелизма (если, конечно, вы не учитесь).

0 голосов
/ 24 марта 2011

Попробуйте установить обработчик необработанных исключений в каждом потоке.В потоке есть функция setUncaughtExceptionHandler ().Реализуйте интерфейс UncaughtExceptionHandler и напечатайте исключение.

Общая идея, но не делайте этого с анонимными классами / методами:

thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
  public void uncaughtException(Thread t, Throwable e)
  {
    e.printStackTrace();
  }
}); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...