谁杀了我的Java无限循环线程?
正如标题所示,我将一些代码包装在谁杀了我的Java无限循环线程?,java,multithreading,memory-management,jvm,kafka-consumer-api,Java,Multithreading,Memory Management,Jvm,Kafka Consumer Api,正如标题所示,我将一些代码包装在while(true)无限循环中,所有代码都被try和catch块完全捕获。这个线程是在main方法中启动的,但是,在长时间运行之后,当我使用jstack检查时,这个工作线程神秘地消失了,导致工作累积 下面是我的代码: public void run() { while (true) { try { // Consumer consumes from Kafka server Global.K
while(true)
无限循环中,所有代码都被try
和catch
块完全捕获。这个线程是在main方法中启动的,但是,在长时间运行之后,当我使用jstack检查时,这个工作线程神秘地消失了,导致工作累积
下面是我的代码:
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();
}
}
}
}
据我所知,这种结构将保持线程运行,消费者也是如此。即使consume()方法失败,它也会无限地重新启动。但是,正如我上面提到的,整个线程在没有任何错误日志的情况下悄无声息地消失。有人能提供一些线索吗
更多可能有用的信息:
您正在捕获
异常
,因此有可能抛出java.lang.Error
或java.lang.Throwable
(例如)
如果您真的想捕获所有内容,那么您需要捕获可丢弃的
,而不仅仅是异常
子类。您的线程可能被错误终止
错误不是例外但它们都扩展了
添加另一个捕获错误的捕获块
决不应捕获可丢弃的内容,因为错误需要与异常不同的处理不是异常。这是一个从可丢弃性衍生出来的错误
如果在您的
消费(主题,处理程序)
中的某个地方抛出了finally,那么finally仍将被调用,将不可避免的延迟大约30秒。。。但在此之后,错误将向上传递,循环将终止。您不应直接使用线程
;使用ExecutorService
(在您的情况下,甚至可能使用ScheduledExecutorService
)。另外,捕获Exception
通常是个坏主意——您甚至可以捕获所有RuntimeException
。但是您没有捕捉到错误
s。这里可能发生的情况是,您触发了一个触发循环结束的OutOfMemoryError
。一般来说,您应该检查您的设计。此外,您可以使用TimeUnit.SECONDS.sleep(30L)
,而不是Thread.sleep()
;但无论如何,一定要使用ScheduledExecutorService
。不要捕获可丢弃的。至少不在这个循环中。这会导致严重的麻烦。一个错误
应该正确处理,而不仅仅是忽略。谢谢!这解释了很多。然而,我很困惑OutOfMemoryError会被抛出到哪里?它会在代码中任意位置随机抛出吗?我已经在这个项目上玩了好几次,每次只有这个线程被终止。那一定是什么原因吧?还有,你能解释一下为什么错误不应该被发现吗?我们应该如何“恰当地”处理它@现实怀疑论者