我们的Java(Web)应用程序在JBoss 6x中运行。 当报告缓慢时:
线程堆栈转储显示在使用以下类型的错误记录时阻止的大多数线程:
waiting for monitor entry [0x000000004b6be000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.jboss.logmanager.handlers.WriterHandler.doPublish(WriterHandler.java:59)
- waiting to lock <0x00002aaac9a2de68> (a java.lang.Object)
at org.jboss.logmanager.ExtHandler.publish(ExtHandler.java:64)
就像这样:
java.lang.Thread.State: BLOCKED (on object monitor)
at java.io.PrintStream.println(PrintStream.java:756)
- waiting to lock <0x00002aaac9817a08> (a com.whatever.SomeClass)
at com.something.ThatClass.thatMethod(ThatClass.java:169)
com.whatever.SomeClass使用org.apache.log4j.Logger
我们使用Log4j进行日志记录。
似乎线程在某些日志记录操作中都被阻止。 过去也出现过此问题,并且似乎是随机的,它会减慢/停止应用程序。
有什么想法吗?
答案 0 :(得分:2)
Jasper,所有日志框架都有一个synchronized块,用于将数据写入磁盘。这是为了防止在多于1个线程写入日志时乱写日志(您发布了一个示例 - java.io.PrintStream.println
上的BLOCKED线程)。
但是有一个解决方案,即使用asynchronous appender。在工作中,我们有一些高吞吐量/低延迟应用程序,我们必须配置它以防止线程争用。
当您使用异步appender时需要考虑的一件事是,如果您的应用程序崩溃或被强制终止,您将看不到日志中的最后一个日志记录语句,因为它们可能不是写入磁盘。