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
happen.
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.
Peter,
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
>
--
Regards,
Shi Jun Zhang