线程处于 WAITING 状态:java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)
Posted
技术标签:
【中文标题】线程处于 WAITING 状态:java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)【英文标题】:Thread is in WAITING state: java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) 【发布时间】:2018-08-27 07:10:40 【问题描述】:我的应用程序负载过重,我的日志低于sudo -u tomcat jstack <java_process_id>
下面的线程正在消费来自 Kafka 的消息,它卡住了。由于该线程处于 WAITING 状态,因此不再消耗 kafka 消息。
"StreamThread-3" #91 daemon prio=5 os_prio=0 tid=0x00007f9b5c606000 nid=0x1e4d waiting on condition [0x00007f9b506c5000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000073aad9718> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at java.util.concurrent.ArrayBlockingQueue.put(ArrayBlockingQueue.java:353)
at ch.qos.logback.core.AsyncAppenderBase.put(AsyncAppenderBase.java:160)
at ch.qos.logback.core.AsyncAppenderBase.append(AsyncAppenderBase.java:148)
at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:84)
at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:51)
at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:270)
at ch.qos.logback.classic.Logger.callAppenders(Logger.java:257)
at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:421)
at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
at ch.qos.logback.classic.Logger.error(Logger.java:538)
at com.abc.system.solr.repo.AbstractSolrRepository.doSave(AbstractSolrRepository.java:316)
at com.abc.system.solr.repo.AbstractSolrRepository.save(AbstractSolrRepository.java:295)
我也找到了这篇文章 WAITING at sun.misc.Unsafe.park(Native Method) 但在我的情况下它对我没有帮助。 在这种情况下,我还能调查什么以获得更多详细信息?
【问题讨论】:
在此堆栈跟踪中,您可以看到在方法AbstractSolrRepository.doSave()
中捕获了一个错误,并尝试从该方法记录它。记录器将错误传递给试图将错误添加到其阻塞队列的附加程序。然后,线程尝试从队列中获取内部锁,但由于线程转储被执行,它没有成功实现,很可能是因为队列已满。也许您发生了级联故障或生成大量日志的事件?
谢谢亚历克斯,我认为你是对的,日志中打印了很多 logger.error 消息。我想更深入地理解这一点。另外我应该为这个实例做什么(如果我不想杀死实例并重新部署怎么办?我的意思是我可以清空那个队列或外部的东西吗?)。
好吧,我可能会尝试解决AbstractSolrRepository
中发生的错误?这个类似乎来自你的代码库?
@AlexandreDupriez 线程并没有尝试获取锁,而是在Condition.await
内,所以它绝对是一个完整的队列,因为put
中唯一可能的调用是notFull.await()
...
@NiravModi 当您说“日志中打印了很多 logger.error 消息”时,这意味着您再次重复产生错误,因此清空队列一次无济于事,因为它会再次填充。通常,当线程处于等待状态时应该不会有问题,因为这意味着现在有更多资源供日志处理程序线程处理排队的消息,因此启动线程最终将继续进行。但主要问题是错误发生率很高。
【参考方案1】:
我也遇到了同样的问题。但是,幸运的是,我通过调整池的大小以及生产者和消费者的数量解决了我的问题。
尝试检查是否有任何方法可以配置以下。
-
线程池的大小
消费者/生产者的数量(如果我们可以在 kafka 中配置)
确保线程池应该有足够的线程来同时为消费者和生产者提供服务。
【讨论】:
以上是关于线程处于 WAITING 状态:java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method)的主要内容,如果未能解决你的问题,请参考以下文章