facebook twitter youtube
in How & Why - 09 Mar, 2012
by Amit Gupta - one comment

In continuation of need & use of synchronization, I am writing this article to reduce overhead of QA sites to solve basic problems related to multithreading. It’ll also clear the actual picture of synchronized.

Lets start with a small program.

public class SynchoTest {
		private Integer a = 10;

		public void acquire(){
			synchronized(a){
				print("acquire()");
				try{
					Thread.sleep(10000);
					print("I have awoken");
					print("" + a);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
			print("Leaving acquire()");
		}


		public void modify(int n){	
			this.a=n;
			print("new value" + a);
		}

		public void display(){
			print("a=" + a);
		}
		:
}

In above program, I am starting 2 threads. Thread A calls method acquire() and Thread B calls modify(97). Remember it, I’ll use it longer in this article.

Output:

2012-03-06 07:48:10.038 :: A: acquire()
2012-03-06 07:48:10.038 :: B: new value97
2012-03-06 07:48:10.038 :: C: a=97
2012-03-06 07:48:20.054 :: A: I have awoken
2012-03-06 07:48:20.054 :: A: 97
2012-03-06 07:48:20.054 :: A: Leaving acquire()

What have you noticed in above output? yes. When A entered in his critical section, a’s value was 10. But when it went to print it, B already changed a’s value. So A prints new value of a ie 97.

Now do some small changes

		public void modify(int n){
			print("Entered in modfy");
			synchronized(a){
				this.a=n;
				print("new value" + a);
			}
		}

Output:

2012-03-06 07:51:46.19 :: A: acquire()
2012-03-06 07:51:46.19 :: B: Entered in modfy
2012-03-06 07:51:46.19 :: C: a=10
2012-03-06 07:51:56.206 :: A: I have awoken
2012-03-06 07:51:56.206 :: A: 10
2012-03-06 07:51:56.206 :: A: Leaving acquire()
2012-03-06 07:51:56.206 :: B: new value97

This time everything is fine. why so?

  1. If there are many synchronized blocks on same object and any thread has entered into one of the synchronized block then no other thread can enter into any synchronized block on the same object. synchronized checks happens-before condition then either it acquire lock or waits until another thread releases lock or get interrupted.
  2. synchronized blocks on different-2 objects has no interrelation. Any thread can enters into any synchronized block. Synchronized(a) and synchronized(this) are also non-related.

Lets play with some more code:

		public void modify(int n){	
			this.a=n;
			print("new value" + a);
		}
		public void display (int n){
			print("a=" + a);
			synchronized(a){
				try{
					Thread.sleep(1000);
					print("a=" + a);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
		}

Output:

a=34
new value45
a=45

Code Postmortem

Thread 1 inserts into synchronized block of display(). It takes lock on a. Thread 2 insert into modify(). But there is no new synchronized block. So it doesn’t check whether some thread has taken lock on a before. So it allows modification in a. Thus display() prints modified value of a.

If I makes modify() synchronized even, it doesn’t change the output.

		public synchronized void modify(int n){	
			this.a=n;
			print("new value" + a);
		}

Because making modify() synchronized ensures that no more than 1 thread can call modify() at a time. It is not related to synchronized(a).

Lets read some more important points about synchronization.

  • If you are starting threads on 2 separate objects then there is no relation between those threads because both objects use different memory address. Hence their synchronized blocks are also not related.
  • synchronized(a) should not contain any statement modifying value of a. You’ll notice it when you’ll read about wait(),notify() etc. However it is allowed.
  • Synchronizing a method or using synchronized(this) everywhere in class is not good practice. Because it blocks all threads to access any synchronized block. Taking lock on necessary field is always a good practice.

Well!! it is not end keep reading of Postmortem of notify(), notifyAll(), and wait()

Amit Gupta

Hey! this is Amit Gupta (amty). By profession, I am a Software Eng. And teaching is my passion. Sometimes I am a teacher, as you can see many technical tutorials on my site, sometimes I am a poet, And sometime just a friend of friends...

Leave a Reply

captcha

  • Matteo //21 Aug 2012

    Great article Amit, thanks a lot!