Deadlock between FileHandler and ConsoleHandler when using customized formatter

Shi Jun Zhang zhangshj at
Mon Dec 9 07:02:17 UTC 2013

On 12/6/2013 12:53 AM, Jason Mehrens wrote:
> Shi Jun Zhang,
> This problem is like hooking up your sink drain to your sink faucet.  
> Even if it you can get it to work you still would not want to use 
> it.   In your code example you could just pre-pend the thread name to 
> the formatter string and return it.

Hi Jason,

This would work and we already have several workarounds including this one.

> However, if you really, really, really, want to attempt this type of 
> trick you have to use JDK8 and create a custom Filter to generate log 
> records.  If you use a filter, you can ditch the thread local in favor 
> of checking the source class of the log record to determine the proper 
> action.  Or if you are using a JDK prior to JDK8 then install the 
> filter on the logger instead of the handler to avoid the locking.

I don't see how Filter can avoid the deadlock, Handler.isLoggable() is 
still called inside Handler.publish(). As long as we call Logger.log 
inside itself with 2 or more handlers in root logger, the deadlock would 

> Peter, Daniel,
> An optimistic tail string would break all formatters that write out 
> summary statistics (num of records, min millis, and max 
> mills).  Instead of changing the formatter synchronization, I think a 
> more useful solution would be to create an AsyncHandler that would 
> disconnect user code from the act of publishing log records.  Then all 
> of handler and formatter locking fall rights into the nice biased 
> locking scenario.


I think you are misunderstanding this problem. This deadlock is not 
related to the formatter synchronization, we can make 
CustomerFormatter.format not synchronized and not call super.format, the 
deadlock still happens.

> Jason
> > Hi Shi Jun Zhang,
> >
> > I have looked at this, creating a prototype. It re-arranged
> > synchronization in a way so that all Formatter methods are invoked out
> > of synchronized sections. I haven't come forward with this yet, because
> > of two issues:
> > - Formatter implementations would suddenly be called multi-threaded.
> > Currently they are invoked from within Handler-instance synchronized
> > sections.
> > - Formatter would have to be invoked optimistically to obtain head and
> > tail strings, so it could happen that a head, for example, would be
> > requested concurrently multiple times, but only one of returned heads
> > would be written to stream then.
> >
> > The 1st thing seems problematic. I can imagine there exist Formatters
> > that are not thread-safe (for example, using single instance of
> > MessageFormat, which is not multi-threaded) and now just happen to work
> > as a consequence of current StreamHandler implementation detail, but
> > would break if called multi-threaded.
> >
> > One way to remedy this is to add a boolean property to Formatter API,
> > say Formatter.isMultiThreaded(), and arrange so that appropriate
> > instances return appropriate values also considering
> > backwards-compatibility...
> >
> > So all-in-all this is not a simple patch and I doubt it can be made for
> > JDK8. In JDK9, I think, it will be possible to re-visit this issue, so
> > It would be good to file it as a BUG or RFI.
> >
> >
> > Regards, Peter
> >


Shi Jun Zhang

More information about the core-libs-dev mailing list