• Post Reply Bookmark Topic Watch Topic
  • New Topic

Synchronisation did not work.  RSS feed

 
Swerrgy Smith
Ranch Hand
Posts: 94
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dear all,

I have a very simple exercise. Given a StringBuffer str with the initial value "A". Three threads will print value of str for 3 times, then add "+" after str, then print it 3 times again. I have to synchronize this process so that three threads with do this sequentially. And here is my code:


The result is bizzare, three threads execute the doit() method in parallel:



However, if I make a little change with the doit() method declaration by removing the synchronized key word and put it inside the method like that:



Then everything is fine, I got the result as expected, only one thread can execute doit() at one moment :



Can any one help me to understand? I use to think that if I put synchronized in the method doit() then only one thread can execute it at one moment?
 
Seema Kekre
Ranch Hand
Posts: 35
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
e1, e2, e3 are all different instances sharing the same StringBuffer object. When you use synchronized method it will lock "this" (Thread instance), which is separate for all 3 hence they dont interfere with each other. But when you lock StringBuffer, since it is the same for all 3 instances, if it is locked by one instance, the others have to wait till it is released.

To achieve what you want try implementing Runnable for Excercise and have its constructor take StringBuffer like before :
Runnable r= new Exercise(str);
Thread t1 = new Thread(r);
Thread t2= new Thread(r);
Thread t3 = new Thread(r);

Then try starting the threads.
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE Ubuntu VI Editor
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In your first example, you are synchronizing on the method, so calls to that method on the same object will be synchronized. You have three different Exercise objects, which call their own synchronized method, so they don't block each other.

In your second example, you are using the StringBuffer as a lock. That StringBuffer is the instance created in main. All three Exercice instances hold the same StringBuffer. So synchronizing on that object will block other thread who attempt to lock it too. That's why the threads wait for each other in that case.
 
Swerrgy Smith
Ranch Hand
Posts: 94
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Seema and Christophe for your replies I understand why now.
 
Nishit Zaveri
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If initialization of str would have been then it would have not given the results you wanted with Christophe/Seema, Please correct me if I'm wrong here.

I believe simple join() would have solved the purpose.
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE Ubuntu VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As you said, if the StringBuffer had been different for each Exercise instance, the problem would have been the same as synchronizing on the method.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!