• Post Reply Bookmark Topic Watch Topic
  • New Topic

Only enter synchronized block if condition is true  RSS feed

 
John Wright
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What is the best design pattern for the following problem: You have a section of code that must be synchronized. Most of the time when someone enters your method that contains this code the condition that determines whether to enter this code will be false. If the condition check is outside the synchronized block 2 threads could run through the body of the synchronized block of code at the one after another if they both evaluate the condition to true. Also while the synchronized code is being executed you don't want other threads to excecute inside the method. Is there a way to achieve this behaviour without synchronizing the condition check. For e.g. the following won't work if you only want to rollover the logs once and you don't want any thread logging during the time the logs are being rolled over.
public class Log
{
public static log(String msg)
{
if (currentTime > timeToRollover)
{
synchronized (Log.class)
{
//write a msg out to the old log, create a new one
// and log a msg to the new one
}
}
logMsg(msg);
}
However the following has poor performance because threads must contend for the monitor to check for rollover time.
public class Log
{
public static log(String msg)
{
synchronized (Log.class)
{
if (currentTime > timeToRollover)
{
//write a msg out to the old log, create a new one
// and log a msg to the new one
}
}
logMsg(msg);
}
 
Girish Pednekar
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
U might want to use the double-checked locking which is a mix of both scenarios. If 2 or more threads get thru the first 'if' simutaneously, only one will enter the 2nd 'if'. the remaining threads will enter the synchronized block but not the 2nd 'if'.

There are instances when double-checked locking may fail e.g. during lazy instantiation. for more details click here. But in your case I believe it should work. Also u might want to synchronize the logMsg(msg) on the Log.Class to make sure no thread is logging a message while the other thread is in the 2nd 'if' creating a new log.
thanks,
GP
[This message has been edited by Girish Pednekar (edited August 15, 2001).]
 
John Wright
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Girish Pednekar:
[B]U might want to use the double-checked locking which is a mix of both scenarios. If 2 or more threads get thru the first 'if' simutaneously, only one will enter the 2nd 'if'. the remaining threads will enter the synchronized block but not the 2nd 'if'.

There are instances when double-checked locking may fail e.g. during lazy instantiation. for more details click here. But in your case I believe it should work.
thanks,
GP[/B]

Thanks for the suggestion. This may prevent 2 threads from doing the rollover but how do you prevent threads from logging during the rollover.
 
Girish Pednekar
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
synchronize the logMsg(msg) similar to the 'if' statement. I believe that should take care of it. the performance problem would still remain though. how about something like below. see if this works.

thanks,
GP
[This message has been edited by Girish Pednekar (edited August 15, 2001).]
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!