logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Trenton D. Adams" <tre...@athabascau.ca>
Subject Re: log4j multithreading performance
Date Fri, 02 Dec 2005 06:19:33 GMT
Trenton D. Adams wrote:
> Curt Arnold wrote:
> 
>>
>> On Dec 1, 2005, at 8:39 PM, Trenton D. Adams wrote:
>>
>>>
>>> As a general rule, singleton methods should not be synchronized for  
>>> performance reasons.  If this method is only called once in awhile,  
>>> no big deal.  But, if it's called regularly, then it can be a  really 
>>> big performance problem.  Does the log4j project have coding  
>>> standards for such things?
>>>
>>> This particular singleton method should check the  
>>> "_defaultLogMonitor" for null first.  If it is not null, it should  
>>> return it.  If it is null, it should synchronize on some object,  
>>> perhaps LF5Appender.class.  Then it should check it for null  again.  
>>> If it is not null, it should return it.  If it is null, it  should 
>>> construct it.
>>>
>>
>> That idiom is not thread-safe but the explanation is too complicated  
>> to go into here.  See "The Double-Checked Locking is Broken"  
>> Declaration (http://www.cs.umd.edu/~pugh/java/memoryModel/ 
>> DoubleCheckedLocking.html).  Also covered on pg 193 of "Effective  
>> Java" which I highly recommend.
> 
> 
> Aha, I see said the blind man.  The variables in the object end up being 
> accessed before full creation of the object is complete.  Sounds like an 
> optimizer bug to me. :)
> 
> You learn something new every day. :)  It's not like a guy is going to 
> check out the assembled code of something so simple, to make sure it's 
> doing it right.  I guess this is one of those things you'd either have 
> to run into, or be told about.
> 
> Ok, now this is me trying to be one of those intelligent thinkers that 
> comes up with a work around.  One of those guys that he mentioned. ;)
> 
> Ok, he mentioned that it works for 32-bit primitive data types, right?
> 
> So, in the event you need performance on a singleton method...
> 
>     if (instanceIndicator == 0)
>     {
>       synchronized (CommandFactory.class)
>       {
>         if (instanceIndicator == 0)
>         {
>           try
>           {
>             commandFactory = new CommandFactory();
>           }
>           catch (Exception exception)
>           {
>             logger.info("error loading CommandFactory", exception);
>             throw exception;
>           }
>         }
>         else
>         {
>           /**
>            * trick any optimizers.  Object was obviously created, by
>            * another thread, before we locked CommandFactory.class
>            */
>           instanceIndicator = 2;
>         }
> 
>         if (instanceIndicator != 2)
>         {
>           /**
>            * only do this if another thread never did create the
>            * object before we locked CommandFactory.class
>            */
>           instanceIndicator = 1;
>         }
>       }
>     }
> 
> 
> So, wouldn't it be completely impossible for an optimizer to put the 
> assignment of the instanceIndicator=1 inside of the if statement, and 
> before the constructor call of CommandFactory()?  Because if it was 
> possible, then this would fail.  But, now that I've done some if/else 
> blocks, it should work.  If the optimizer moves the "if 
> instanceIndicator != 2" block into the "if (instanceIndicator == 0)" 
> block, then it would actually end up becoming a logic error.  So, the 
> optimizer wouldn't do that, unless it had a bug.
> 
> FYI : If I didn't have all the if/else statements, the optimizer could 
> potentially move instanceIndicator = 1 into the first *if* block, 
> because it doesn't matter where it get's assigned, as it would look (to 
> the optimizer) like it wasn't used in some sort of logic, so optimizing 
> would be ok.  But now that there's logic, it can't optimize.  Perhaps I 
> have no out logiced the optimizer logic!
> 
> Ok, I was just having fun theorizing.  LOT's of fun!!!  :P  Any thoughts 
> anyhow?  I think I'm right! LOL :D

Wait a second, does it even need to be that complex.  Will optimizers
move the actual order of java assignments?

So, couldn't I go like this?

>           try
>           {
>             commandFactory = new CommandFactory();
               instanceIndicator = 1;
>           }
>           catch (Exception exception)
>           {
>             logger.info("error loading CommandFactory", exception);
>             throw exception;
>           }

Could the optimizer move the "instanceIndicator = 1" up one line? 
Perhaps by analyzing exactly what's happening it could, because it 
knows, or *thinks* it won't affect anything.

> 
> __    This communication is intended for the use of the recipient to 
> whom it
>    is addressed, and may contain confidential, personal, and or privileged
>    information. Please contact us immediately if you are not the intended
>    recipient of this communication, and do not copy, distribute, or take
>    action relying on it. Any communications received in error, or
>    subsequent reply, should be deleted or destroyed.
> ---
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message