Multithreading in Java 4
Synchronization in Java
At times when more than one thread try to access a shared resource, we need to ensure that resource will be used by only one thread at a time. The process by which this is achieved is called synchronization. The synchronization keyword in java creates a block of code referred to as critical section.
General Syntax :
synchronized (object)
{
//statement to be synchronized
}
Q. Why we use Syncronization ??
If we do not use syncronization, and let two or more threads access a shared resource at the same time, it will lead to distorted results.
Consider an example, Suppose we have two different threads T1 and T2, T1 starts execution and save certain values in a file temporary.txt which will be used to calculate some result when T1 returns. Meanwhile, T2 starts and before T1 returns, T2 change the values saved by T1 in the file temporary.txt (temporary.txt is the shared resource). Now obviously T1 will return wrong result.
To prevent such problems, synchronization was introduced. With synchronization in above case, once T1 starts using temporary.txt file, this file will be locked(LOCK mode), and no other thread will be able to access or modify it until T1 returns.
Thread Synchronization
There are two types of thread synchronization mutual exclusive and inter-thread communication.
1) Mutual Exclusive.
1. Synchronized method.
2. Synchronized block.
3. static synchronization.
2) Cooperation (Inter-thread communication in java)
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This can be done by three ways in java :
1) by synchronized method
2) by synchronized block
3) by static synchronization
1) Using Synchronized Methods
Using Synchronized methods is a way to accomplish synchronization. But lets first see what happens when we do not use synchronization in our program.
Example with no Synchronization
class First
{
public void display(String msg)
{
System.out.print ("["+msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]");
}
}
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{
fobj = fp;
msg = str;
start();
}
public void run()
{
fobj.display(msg);
}
}
public class Syncro
{
public static void main (String[] args)
{
First fnew = new First();
Second ss1 = new Second(fnew, "welcome");
Second ss2= new Second (fnew,"new");
Second ss3 = new Second(fnew, "programmer");
}
}
Output :
[welcome [ new [ programmer]
]
]
In the above program, object fnew of class First is shared by all the three running threads(ss1, ss2 and ss3) to call the shared method(void display). Hence the result is unsynchronized and such situation is called Race condition.
Synchronized Keywoed
To synchronize above program, we must serialize access to the shared display() method, making it available to only one thread at a time. This is done by using keyword synchronized with display() method.
synchronized void display (String msg) //Synchronized method
2) Using Synchronized block
Synchronized block can be used to perform synchronization on any specific resource of the method.
Suppose you have 50 lines of code in your method, but you want to synchronize only 5 lines, you can use synchronized block.
If you put all the codes of the method in the synchronized block, it will work same as the synchronized method.
Syntax:
synchronized (object referenced)
{
//statement to be synchronized
}
Points to remember for Synchronized block :
1) Synchronized block is used to lock an object for any shared resource.
2) Scope of synchronized block is smaller than the method
class First
{
public void display(String msg)
{
System.out.print ("["+msg);
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println ("]");
}
}
class Second extends Thread
{
String msg;
First fobj;
Second (First fp,String str)
{
fobj = fp;
msg = str;
start();
}
public void run()
{
synchronized(fobj) //Synchronized block
{
fobj.display(msg);
}
}
}
public class Syncro
{
public static void main (String[] args)
{
First fnew = new First();
Second ss1 = new Second(fnew, "welcome");
Second ss2= new Second (fnew,"new");
Second ss3 = new Second(fnew, "programmer");
}
}
Output :
[welcome]
[new]
[programmer]
Because of synchronized block this program gives the expected output.
3) Static Synchronization
If you make any static method as synchronized, the lock will be on the class not on object.
Problem without static synchronization.
Suppose there are two objects of a shared class(e.g. Table) named object1 and object2. In case of synchronized method and synchronized block there cannot be interference between t1 and t2 or t3 and t4 because t1 and t2 both refers to a common object that have a single lock. But there can be interference between t1 and t3 or t2 and t4 because t1 acquires another lock and t3 acquires another lock. I want no interference between t1 and t3 or t2 and t4. Static synchronization solves this problem.
Example of static synchronization
In this example we are applying synchronized keyword on the static method to perform static synchronization.
class Table{
synchronized static void printTable(int n){ // static synchronization
for(int i=1;i<=3;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){}
}
}
}
class MyThread1 extends Thread{
public void run(){
Table.printTable(1);
}
}
class MyThread2 extends Thread{
public void run(){
Table.printTable(10);
}
}
class MyThread3 extends Thread{
public void run(){
Table.printTable(100);
}
}
class MyThread4 extends Thread{
public void run(){
Table.printTable(1000);
}
}
public class TestSynchronization4{
public static void main(String t[]){
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
MyThread3 t3=new MyThread3();
MyThread4 t4=new MyThread4();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
Output :
1
2
3
10
20
30
100
200
300
1000
2000
3000
No comments:
Post a Comment
Hai , Post your comment . (required, Bugs, Errors )