Solved

static synchronized v/s synchronized

Posted on 2013-02-06
9
258 Views
Last Modified: 2013-02-18
hi guys

When should i use scenario1 v/s scenario 2

scenario 1
public synchronized Properties getInstance()
      {
            if (self == null)
            {
                  self = new Properties();
            }
            
            return self;
      }


scenario 2
public static synchronized Properties getInstance()
      {
            if (self == null)
            {
                  self = new Properties();
            }
            
            return self;
      }

In case of  static synchronized  i understand that the thread acquires a lock on the
'Class' and not the object. What are the implication of this ?

thanks
0
Comment
Question by:royjayd
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 13

Assisted Solution

by:F Igor
F Igor earned 25 total points
ID: 38861757
The basic implication is by calling the static method you get lock for all objects of this class,
and only one at the same time can perform the call. See java documentation at:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.3.6

And some examples and explanations at:

http://stackoverflow.com/questions/6443872/java-static-synchronized
http://stackoverflow.com/questions/437620/java-synchronized-static-methods-lock-on-object-or-class/437627#437627

Additionally, you can use some specific locking using Lock class
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html
0
 
LVL 35

Assisted Solution

by:mccarl
mccarl earned 133 total points
ID: 38861905
When should i use scenario1 v/s scenario 2
I think at this point you are thinking a bit more into it than you need. The choice between your two scenarios above, would in NO way be based on synchronization. Whether you choose static or non-static method would be just a decision for the design of your application, ie. does it make sense for the method to be static or not.

Only then, would one start considering synchronization issues, ie. does the method need to be synchronized? Do you use the implicit synchronization object (ie. the Class or the instance object that is demonstrated above)? Or do you create your own object to explicitly lock on?

Yeah, but the point is static vs non-static is chosen for other reason that how the synchronization might work. Hope that makes sense!
0
 
LVL 26

Assisted Solution

by:ksivananth
ksivananth earned 25 total points
ID: 38862764
if you follow below inner class implementation, you don't have to synchronize at all and still you achieve lazy initialization,


public class LazySingleton{
	
	public void test(){
		System.out.println( "test method called" ) ;
	}
	
	public static void staticTest(){
		System.out.println( "staticTest method called" ) ;
	}
	
	public static LazySingleton getInstance(){
		System.out.println( "getInstance is called" ) ;
		return LazySingletonInstance.getLazySingletonInsance() ;
	}
	
	
	private static class LazySingletonInstance{
		private static LazySingleton instance = new LazySingleton() ;
		static{
			System.out.println( "static block called" ) ;
		}
		
		public static LazySingleton getLazySingletonInsance(){
			System.out.println( "getLazySingletonInsance is called" ) ;
			return instance ;
		}
	}
}

Open in new window

0
 
LVL 26

Assisted Solution

by:dpearson
dpearson earned 217 total points
ID: 38862916

When should i use scenario1 v/s scenario 2

You should use scenario 2 :)

The reason is that scenario 2 is part of a standard pattern where  the "self" variable itself is declared as static:

private static Properties self ;

and you then access it with:
Properties.getInstance() -- returns "self".  

To do that correctly in a multithreaded environment you need the "static synchronized" as you have it defined.

Scenario1 doesn't really make sense here, as you'd only use it if you had defined
   private Properties self;
inside the class and the access pattern would have to be:

self.getInstance() -- which just returns "self"...which is pointless (you have to have 'self' in order to call it).

So the answer is you should use scenario 2.
 
Doug
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:royjayd
ID: 38864097
Lets say i go with scneario 2

public class Properties{
private static self;
private Properties() {
super();
try {
UtildbProperties setEnvironment= UtilDBPropertyLoader.loadPropertyFromDB()

/*UtilDBPropertyLoader.loadPropertyFromDB() is invoking a complex store procedure
and can be time consuming.*/

}
catch (Exception e) 
{
}
}

public static synchronized Properties getInstance()
      {
            if (self == null)
            {
                  self = new Properties();
            }
            
            return self;
      }
     
      public int getTimeofComplexOperation(){
      /* code to calculate time of operation*/
      }

} //close the class

Open in new window


Now lets say in the JVM i have 10 instances of this class by 10 different users
and each user trying to access Properties.getInstance();  

Properties p1instance = Properties.getInstance();   //by user 1

Properties p2instance = Properties.getInstance();   //by user 2
...
Properties p10instance  =  Properties.getInstance(); //by user 10

If i understand correctly when a thread 1 (user 1)does
Properties.getInstance();   it acquires a lock on the getInstance() and the lock is the
'class' (Properties) .
now all other users will NOT be able to invoke Properties.getInstance() until
user1 has released the lock
Lets say Properties() constructor has some expensive and time consuming operation as shown in the sample code above.

So you still think its good idea to go with static ? Since now you are locking the
getInstance() method for all other users. If getInstance() hangs, all other instances will hang forever, correct ?


thanks.
0
 
LVL 35

Accepted Solution

by:
mccarl earned 133 total points
ID: 38866405
If i understand correctly when a thread 1 (user 1)does
Properties.getInstance();   it acquires a lock on the getInstance() and the lock is the
'class' (Properties)
Not exactly how I would write it, but I think you have the idea, YES!

now all other users will NOT be able to invoke Properties.getInstance() until
user1 has released the lock
Correct!

So you still think its good idea to go with static ?
YES!! As I said before, forget about the locking aspect for a moment (don't worry we will come back to it).

Now, imagine if this method was non-static (and the 'self' variable was non-static, it doesn't really make sense for them to have different modifiers). Now all of your 10 users (instances) will each call the time-consuming operation themselves, and they will all wait a long time to until the method returns. Now also, imagine that at a later time (after all those 10 instances have called this method and returned) another instance calls this method... It TOO will call load the properties again and spend a long time in this method.

However, if this method is static (and 'self' is static) and lets firstly assume that those 10 instances call this method at different times, the first call will wait a long time while the properties load, but then ANY instance after that will just access the previous set self variable and return (almost) immediately.

So as I was saying above, you first choice, without considering synchronization, is that you definitely SHOULD make that method (and self) static, in order to implement caching.


Only NOW, should you think about synchronization issues... From the above, you can see that it that (static) method is called a number of times, while previous calls are still loading the properties, 'self' will still be null, and the long running property load will still get called multiple times. SO, as you have done here, you add synchronized to the method, and now you know that only one thread/user/instance/etc can be in this method at the one time. This guarantees that the first one to call it, will do the property load and set the 'self' variable, and all others will wait (if needed) for this to happen and then just access 'self' to get it's properties.


So now to your concerns, YES, if 10 instances call this method at the same time, one will do the property load operation and the other 9 will wait on the lock. BUT, why is this a bad thing? If this wasn't the case, those other 9 would still have to spend a long time loading the properties themselves or getting that information some other way. However, if any instance calls this method after the properties have loaded, for the rest of the life of this app, they will all return (almost) immediately. You can't get away from the fact that those initial instances will wait on the lock, but what else can you do.. *your properties jsut aren't loaded yet*

If getInstance() hangs, all other instances will hang forever, correct ?
Correct! But, even if it wasn't synchronized or it wasn't static, if getInstance *IS* going to hang, wouldn't it hang for all calls to it from all instances? What might be different between one call or another call?   If it is at all possible the getInstance() can really *hang*, then getInstance() should be fixed so that it CAN'T hang!!! ;)
0
 
LVL 26

Assisted Solution

by:dpearson
dpearson earned 217 total points
ID: 38866464

Lets say Properties() constructor has some expensive and time consuming operation as shown in the sample code above.

So you still think its good idea to go with static ? Since now you are locking the
getInstance() method for all other users. If getInstance() hangs, all other instances will hang forever, correct ?

Yes this is all correct and indeed that's the idea behind this pattern.

E.g. Say I want my application to use a dictionary that contains 100,000 words.  You could use this pattern to load the dictionary.  The first thread triggers the dictionary to load and blocks all other threads while it is loading.  Once it's finished loading, all threads proceed and from then on each can get the dictionary safely (and quickly).

If you used scenario 1 instead, then each thread would load the dictionary - which is a lot of memory and CPU wasted (since the dictionary is always the same - better to share one than each make its own copy).  They wouldn't block each other, but each would have to do the same work as the first thread - so in practice they would all finish more slowly (10 threads each loading a dictionary is usually slower than 1 loading it and then the rest getting a copy almost instantly after the load finishes).

If a constructor can "hang" (i.e. never return) you've got a broken app anyway.  Instead, you should think in terms of "fail to work" - which is fine.  If for example the dictionary failed to load, the first thread would throw an exception from the constructor, releasing the synchronized lock and allowing the next thread to try to load the dictionary.

Doug
0
 

Author Comment

by:royjayd
ID: 38890306
thanks doug.
I understand your example when you said >>
since the dictionary is always the same - better to share one than each make its own copy.

Lets say we replace this dictionary with a timesheet. Each of these 10 threads would have
its own version of the timesheet. so in that case do you think scenario 1 would have a preference over scenario 2 ?
0
 
LVL 26

Expert Comment

by:dpearson
ID: 38890966
If it's not a shared resource then there's no need to be concerned with synchronization at all.  If I have an object A and you have an object B (e.g. two unrelated timesheets) then each thread can work on their respective objects without any interaction and without any synchronized methods.

So then the pattern would become just:
public Properties getInstance() {
  ...
}

It wouldn't do any harm to make this:
public synchronized Properties getInstance() {
}

but it also wouldn't be protecting you from anything as each thread is working with a different instance of the class anyway.  synchronized here would effectively do nothing.

Doug
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
mergeTwo  challenge 13 72
commonTwo  challenge 63 98
topping2 challenge 13 59
Running Jira on Raspberry PI 2? 3 127
After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
This video teaches viewers about errors in exception handling.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now