Deadlock between FileHandler and ConsoleHandler when using customized formatter

Shi Jun Zhang zhangshj at linux.vnet.ibm.com
Thu Nov 28 07:53:44 UTC 2013


Hi,

We get a deadlock between java.util.logging.FileHandler and 
java.util.logging.ConsoleHandler when we are using a customized 
formatter in these handlers.

Here is the simple test case. 
http://cr.openjdk.java.net/~zhangshj/deadlockInHandlers/deadlockInHandlers.zip

Run "java -Djava.util.logging.config.file=logging.properties 
TestThread", it will hang immediately.

And this is the stack trace in dump file
"Thread-1":
     at java.util.logging.StreamHandler.publish(StreamHandler.java:205)
     - waiting to lock <0x00000000ec52e0c0> (a 
java.util.logging.ConsoleHandler)
     at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:118)
     at java.util.logging.Logger.log(Logger.java:617)
     at java.util.logging.Logger.doLog(Logger.java:638)
     at java.util.logging.Logger.log(Logger.java:661)
     at java.util.logging.Logger.info(Logger.java:1289)
     at CustomerFormatter.format(CustomerFormatter.java:16)
     at java.util.logging.StreamHandler.publish(StreamHandler.java:210)
     - locked <0x00000000ec51ab90> (a java.util.logging.FileHandler)
     at java.util.logging.FileHandler.publish(FileHandler.java:614)
     - locked <0x00000000ec51ab90> (a java.util.logging.FileHandler)
     at java.util.logging.Logger.log(Logger.java:617)
     at java.util.logging.Logger.doLog(Logger.java:638)
     at java.util.logging.Logger.log(Logger.java:661)
     at java.util.logging.Logger.info(Logger.java:1289)
     at TestThread$1.run(TestThread.java:14)
     at java.lang.Thread.run(Thread.java:724)
"Thread-2":
     at java.util.logging.FileHandler.publish(FileHandler.java:611)
     - waiting to lock <0x00000000ec51ab90> (a 
java.util.logging.FileHandler)
     at java.util.logging.Logger.log(Logger.java:617)
     at java.util.logging.Logger.doLog(Logger.java:638)
     at java.util.logging.Logger.log(Logger.java:661)
     at java.util.logging.Logger.info(Logger.java:1289)
     at CustomerFormatter.format(CustomerFormatter.java:16)
     at java.util.logging.StreamHandler.publish(StreamHandler.java:210)
     - locked <0x00000000ec52e0c0> (a java.util.logging.ConsoleHandler)
     at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:118)
     at java.util.logging.Logger.log(Logger.java:617)
     at java.util.logging.Logger.doLog(Logger.java:638)
     at java.util.logging.Logger.log(Logger.java:661)
     at java.util.logging.Logger.info(Logger.java:1289)
     at TestThread$1.run(TestThread.java:14)
     at java.lang.Thread.run(Thread.java:724)

The problem is that we use a logger in CustomerFormatter and this causes 
Logger.log call Logger.log itself. As FileHandler.publish and 
StreamHandler.publish is synchronized, but the iteration to call publish 
method for all handlers in Logger.log is not synchronized, the deadlock 
happens.

This violates the Java doc for java.util.logging.Logger that says "All 
methods on Logger are multi-thread safe."

Currently we have 2 workarounds.
First is to add 2 lines in the logging.properties to force 
CustomerFormatter use new instance of FileHandler and ConsoleHandler 
like this,
CustomerFormatter.handlers = java.util.logging.FileHandler, 
java.util.logging.ConsoleHandler
CustomerFormatter.useParentHandlers = false

Second is to synchronize the logger.info call in TestThread test case.

I'm not sure whether we should fix this problem in JDK. The fix I can 
image is to synchronize each call to handler.publish() in Logger.log, 
but I think this would cause performance degradation.

Another solution is to add some documents in Java doc to state that 
Logger is not "so much" multi-thread safe.

Any suggestion or better fix?

-- 
Regards,

Shi Jun Zhang




More information about the core-libs-dev mailing list