4

Как видно из названия, у меня есть код, завернутый в бесконечный цикл while(true), и все они полностью пойманы try и catch. Однако этот поток запускается в основном методе, однако после длительного запуска этот рабочий поток исчезает таинственным образом, когда я проверяю использование jstack и заставляя работу накапливаться.Кто убил My Java Infinite loop thread?

Ниже мой код:

public void run() { 
    while (true) { 
     try { 
      // Consumer consumes from Kafka server 
      Global.KAFKA_METRIC_DATA_CONSUMER.consume(topic, handler); 
     } catch (Exception e) { 
      logger.error("Kafka consumer process was interrupted by exception!"); 
     } finally { 
      try { 
       // Prevent restart too often 
       Thread.sleep(30 * BaseConst.SECOND); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Для моего понимания, эта структура будет держать нить работает так потребитель. Даже если методы потребления() не удались, он перезапустится бесконечно. Однако, как я уже упоминал выше, вся нить исчезает без какого-либо журнала ошибок. Может ли кто-нибудь дать подсказку, пожалуйста?

Некоторые больше информации, которые могут быть полезны:

  1. Я проверил метод потреблять никогда не выключит потребитель ни закрыть сокет к серверу. Он будет постоянно пытаться подключиться к серверу после сбоя .
  2. Я проанализировал свалку кучи java, и я обнаружил, что есть утечка памяти где-то еще в проекте, что очень часто вызывает оккупацию памяти high и gc. Тем не менее, основным методом остается бег.
+1

Вы не должны использовать 'Thread' напрямую; вместо этого используйте «ExecutorService» (возможно, даже «ScheduledExecutorService» в вашем случае). Кроме того, ловить «Исключение» - это плохая идея в целом - вы даже поймаете все «RuntimeException». Но ... Вы не поймаете 'Ошибка'. Что, вероятно, происходит здесь, так это то, что вы активировали, скажем, «OutOfMemoryError», которые запустили цикл до конца. В более общем плане вы должны рассмотреть свой дизайн. – fge

+0

Кроме того, вместо '' Thread.sleep() 'вы можете использовать' TimeUnit.SECONDS.sleep (30L) '; но в любом случае использовать «ScheduledExecutorService». – fge

ответ

9

OutOfMemoryError не является исключением. Это ошибка, полученная от Throwable.

Если это было брошено где-то в вашем consume(topic, handler), то, наконец, все равно будет вызвано, задерживая неизбежные 30 секунд ... но после этого ошибка будет передана вверх, и ваш цикл будет прекращен.

+3

Проголосовало за * не * рекомендую ловить 'Throwable' ... – RealSkeptic

+0

Спасибо! Это многое объясняет. Тем не менее, я смущен тем, куда будет выброшен OutOfMemoryError? Будут ли они выбрасываться в любом месте кода случайным образом? Я несколько раз играл с этим проектом, и происходит, что каждый раз только этот поток убивается. Это должна быть какая-то причина, верно? И не могли бы вы объяснить больше, почему Ошибка не должна быть поймана? Как мы должны иметь дело «правильно»? @RealSkeptic – Chen

1

Вы ловли Exception так что есть шанс, что java.lang.Error или java.lang.Throwable выбрасывают (например OutOfMemoryError)

Если вы действительно хотите, чтобы поймать все, вам нужно, чтобы поймать Throwable и не только Exception подклассы.

+2

Не ловите «Throwable». По крайней мере, не внутри этого цикла. Это может привести к серьезным неприятностям. «Ошибка» следует обрабатывать должным образом, а не просто игнорировать. – RealSkeptic

0

Ваша ветка, вероятно, убита ошибкой.

Ошибка не является исключением! Но они оба распространяются Throwable

Добавить еще один блок catch, который обнаруживает ошибки.

Throwable никогда не должны быть пойманы, поскольку ошибки требуют иного обращения, чем исключения