dev@glassfish.java.net

Re: a more efficient way to initialize Loggers?

From: Peter Williams <Pete.Williams_at_Sun.COM>
Date: Thu, 07 Dec 2006 12:01:58 -0800

Peter Williams wrote:
> Lloyd L Chambers wrote:
>> Please see:
>>
>> https://glassfish.dev.java.net/issues/post_bug.cgi
>>
>> ------------
>> Initializing all the Loggers at startup
>> [ServerLogManager.reInitializeServerLoggers] takes about half a
>> second even on a very fast machine.
>>
>> But observe that many Loggers are never used unless an exception
>> needs to be reported. The typical
>> idiom is: try { ... } catch( ... ) { _logger.log(...); }.
>>
>> Thus, a cost is paid even if the logger is never used. Additionally,
>> Loggers cannot be initialized at
>> startup because the ServerContext is not yet available. This causes
>> wasted cycles and leads to a
>> transient half-initialized state which much be protected against
>> internally.
>>
>> We might be see some performance improvements by deferring the
>> initialization of Loggers. This would
>> need to be done in a thread-safe manner. I think the following code
>> snippet is thread-safe and would
>> remain efficient, especially if applied only to cases where the
>> Logger is needed only for exceptions:
>>
Actually maybe I'm mistaken. Java Concurrency in Practice says that
using volatile fixes this pattern in JVM 5.0 onward so I guess it's ok.

-Peter

> This is the double checked locking pattern and is NOT thread safe.
> See
> http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
> for an exhaustive academic analysis if interested.
>
> -Peter
>>
>> private static Logger
>> getLogger() {
>> // if it's non-null, then it's safe to return it
>> if ( _logger != null ) {
>> return _logger;
>> }
>>
>> // null, synchronize before getting the logger
>> synchronized( StringManagerBase.class ) {
>> if ( _logger == null ) {
>> _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER)
>> }
>> }
>> return _logger;
>> }
>>
>> This could be captured in a class for convenience:
>>
>>
>> static private final class LoggerGetter {
>> private final String mLoggerName;
>> private volatile Logger mLogger;
>>
>> public LoggerGetter( final String loggerName ) {
>> mLoggerName = loggerName;
>> mLogger = null;
>> }
>> public Logger
>> getLogger() {
>> // if it's non-null, then it's safe to return it
>> if ( mLogger != null ) {
>> return mLogger;
>> }
>> else synchronized( this ) {
>> if ( mLogger == null ) {
>> mLogger=LogDomains.getLogger(LogDomains.UTIL_LOGGER)
>> }
>> }
>> return mLogger;
>> }
>> }
>>
>> and used like this:
>> static private final LoggerGetter _loggerGetter = new LoggerGetter(
>> "MyLogger" );
>> static private Logger _getLogger() { return _loggerGetter.getLogger(); }
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>
>
>