Synchronization

In this section, you will learn about the synchronization.

Synchronization

Synchronization

     

Threads commonly share the same memory space area, that?s why they can share the resources. Threads commonly communicate by sharing access to fields and the objects reference fields refer to. This communication type is extremely efficient, but makes two kinds of problems: thread interference and memory consistency errors. By the synchronization tool we can avoid this problem. In other words, There is very critical situation where we want only one thread at a time has to access a shared resources. For example, suppose two people each have a checkbook for a single account same as like two different threads are accessing the same account data.
 
Lock
  
This term refers to the access granted to a particular thread that can access the shared resources. At any given time, only one thread can hold the lock and thereby have access to the shared resource. Every object in Java has build-in lock that only comes in action when the object has synchronized method code. By associating a shared resource with a Java object and its lock, the object can act as a guard, ensuring synchronized access to the resource. Only one thread at a time can access the shared resource guarded by the object lock.
  
Since there is one lock per object, if one thread has acquired the lock, no other thread can acquire the lock until the lock is not released by first thread. Acquire the lock means the thread currently in synchronized method and released the lock means exits the synchronized method. Remember the following points related to lock and synchronization:

  • Only methods (or blocks) can be synchronized, Classes and variable cannot be.
     
  • Each object has just one lock.
      
  • All methods in a class need not to be synchronized. A class can have both synchronized and non-synchronized methods.
     
  • If two threads wants to execute a synchronized method in a class, and both threads are using the same instance of the class to invoke the method then only one thread can execute the method at a time.
     
  • If a class has both synchronized and non-synchronized methods, multiple threads can still access the class's non-synchronized methods. If you have methods that don't access the data you're trying to protect, then you don't need to synchronize them. Synchronization can cause a hit in some cases (or even deadlock if used incorrectly), so you should be careful not to overuse it.
      
  • If a thread goes to sleep, it holds any locks it has?it doesn't release them.
      
  • A thread can acquire more than one lock. For example, a thread can enter a synchronized method, thus acquiring a lock, and then immediately invoke a synchronized method on a different object, thus acquiring that lock as well. As the stack unwinds, locks are released again.
     
  • You can synchronize a block of code rather than a method.
     
  • Constructors cannot be synchronized

There are two ways to synchronized the execution of code:

  1. Synchronized Methods
     
  2. Synchronized Blocks (Statements)

Synchronized Methods

If any method is specified with the keyword synchronized then this method of an object is only executed by one thread at a time. A any thread want to execute the synchronized method, firstly it has to obtain the objects lock. Acquire the method is simply by calling the method. If the lock is already held by another thread, then calling thread has to wait. 
 
Synchronized methods are useful in those situations where methods can manipulate the state of an object in ways that can corrupt the state if executed concurrently. Stack implementations usually define the two operations push and pop of elements as synchronized, that?s why pushing and popping are mutually exclusive operations. For Example if several threads were sharing a stack, if one thread is popping the element on the stack then another thread would not be able to pushing the element on the stack.
 

The following program demonstrates the synchronized method:

public class SynThread{
	public static void main(String args[]){
		Share s=new Share();
		MyThread m1=new MyThread(s,"Thread1");
		MyThread m2=new MyThread(s,"Thread2");
		MyThread m3=new MyThread(s,"Thread3");
	}
}
class MyThread extends Thread{
	Share s;
	MyThread(Share s,String str){
		super(str);
		this.s=s;
		start();
	}
	public void run(){
		s.doword(Thread.currentThread().getName());
	}
}
class Share{
	public synchronized void doword(String str){
		for(int i=0;i<5;i++){
		System.out.println("Started   :"+str);
		try{
			Thread.sleep(100);
		}catch(Exception e){}
		}
	}
}

Output of the program is:

C:\j2se6\thread>javac SynThread.java

C:\j2se6\thread>java SynThread
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread2
Started :Thread2
Started :Thread2
Started :Thread2
Started :Thread2

C:\j2se6\thread>

Download this example

Synchronized Blocks (Statements)

A synchronized statement is another way to create synchronized code. Synchronized statements must specify the object that provides the intrinsic lock. The synchronized block allows execution of arbitrary code to be synchronized on the lock of an arbitrary object.

General form of synchronized block is:
synchronized (object reference expression)
{
code block..
}

The following program demonstrates the synchronized block:

public class SynStatement{
	public static void main(String args[]){
		Share s=new Share();
		MyThread m1=new MyThread(s,"Thread1");
		MyThread m2=new MyThread(s,"Thread2");
		MyThread m3=new MyThread(s,"Thread3");
	}
}
class MyThread extends Thread{
	Share s;
	MyThread(Share s,String str){
		super(str);
		this.s=s;
		start();
	}
	public void run(){
		s.doword(Thread.currentThread().getName());
	}
}
class Share{
	public void doword(String str){
		synchronized(this){
		for(int i=0;i<5;i++){
		System.out.println("Started   :"+str);
		try{
			Thread.sleep(100);
		}catch(Exception e){}
		}
		}
	}
}

Output of the program is:


C:\j2se6\thread>javac SynStatement.java

C:\j2se6\thread>java SynStatement
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread1
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread3
Started :Thread2
Started :Thread2
Started :Thread2
Started :Thread2
Started :Thread2

C:\j2se6\thread>

Download this example