Java поток заканчивается досрочно и подозрительно - PullRequest
5 голосов
/ 27 апреля 2009

У меня есть следующий код в Runnable, который передается в поток t:

public void run() {
        logger.debug("Starting thread " + Thread.currentThread());

        try {
            doStuff();
        } catch (Exception e) {
         logger.debug("Exception in Thread " + Thread.currentThread());
        } 

        logger.debug("End of thread " + Thread.currentThread());
    }

Я столкнулся с ошибкой, когда вижу тупик при следующих условиях

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

Есть ли какой-то волшебный способ, которым этот поток мог прерваться раньше, не регистрируя сообщение о завершении потока ИЛИ не создавая исключение?

Ответы [ 5 ]

7 голосов
/ 27 апреля 2009

Вы уверены, что doStuff() не бросил Error? Измените catch (Exception e) на catch (Throwable t). Можно убить потоки в Java с помощью Thread.stop(), но это маловероятно.

1 голос
/ 27 апреля 2009

Когда вы ловите Exception, вы поймаете любой RunnableException и любой объявленный брошенный Exception, но вы не поймаете ничего, что расширяет Error. Если вы действительно хотите поймать любую вещь, то вам нужно поймать Throwable.

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

public void run() {
  logger.debug("Starting thread " + Thread.currentThread());
  try {
    // The work of your Thread
  } finally {
    logger.debug("End of thread " + Thread.currentThread());
  } 
}

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

В большинстве моих программ я устанавливаю UncaughtExceptionHandler , чтобы я знал о каждом потоке, который неожиданно умирает. Это была огромная помощь в отслеживании сбоев. Это было добавлено к языку с Java 5.

1 голос
/ 27 апреля 2009

Вы уверены, что там, где вы start () Thread, вы также join () it впоследствии?

Runnable myRunnable=new Runnable(){
  @Override
  public void run(){
    // your original code goes here
  }
};

Thread myThread=new Thread(myRunnable);

myThread.start();

myThread.join(); // magic happens here! it waits for the thread to finish ;)

Кстати, join () может выдать InterruptedException , так что если что-то прерывает ваш поток во время его работы, join сообщит вам об этом, выдав это исключение.

Надеюсь, это поможет.

0 голосов
/ 27 апреля 2009

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

0 голосов
/ 27 апреля 2009

Конечно, поток может быть прерван после конца блока try/catch, но до последнего оператора logger.debug. В этом случае он выдаст InterruptedException, что, в принципе, может нигде не записываться (если обработчик исключений по умолчанию настроен на игнорирование таких вещей).

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

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