Wednesday, 17 July 2013

Synchronized Block in Java with Example

Synchronized block is used to acquire a lock on the Object specified in the block.

Lets see this with an example : (Using Synchronized Method)

Class App.java
package threadEx;

public class App {

public static void main(String[] args) {
// TODO Auto-generated method stub
new Worker().main();

}

}

Class Worker.java
package threadEx;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Worker {
Random r=new Random();

private List<Integer> al1=new ArrayList<Integer>();
private List<Integer> al2=new ArrayList<Integer>();

public synchronized void stageOne(){

try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al1.add(r.nextInt(100));
}

public synchronized void stageTwo(){

try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al2.add(r.nextInt(100));

}


public void process(){
for(int i=0;i<1000;i++){
stageOne();
stageTwo();

}
}

public void main(){

System.out.println("Starting.....");
long start=System.currentTimeMillis();
//process();
Thread t1=new Thread(new Runnable() {

@Override
public void run() {
process();

}
}) ;

Thread t2=new Thread(new Runnable() {

@Override
public void run() {
process();

}
}) ;
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end=System.currentTimeMillis();
System.out.println("time taken"+(end-start));
System.out.println("List1:"+al1.size()+"List2:"+al2.size());

}


}

If we run the program without SYNCHRONIZED METHOD ,then the time taken will return 2000(appx.) ie 2 sec but the list size will display different values as opposed to 1000 n 1000.

If we run in SYNCHRONIZED METHOD , the arraylist size returns exactly 1000 n 1000 but the time taken is doubled, ie 4000(4 sec).
This is due to synchronized is call on Worker object.

USING SYNCHRONIZED BLOCK

package threadEx;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Worker {
Random r=new Random();
Object lock1=new Object();
Object lock2=new Object();

private List<Integer> al1=new ArrayList<Integer>();
private List<Integer> al2=new ArrayList<Integer>();

public synchronized void stageOne(){

synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al1.add(r.nextInt(100));
}


}

public synchronized void stageTwo(){

synchronized (lock2) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
al2.add(r.nextInt(100));

}


}

public void process(){
for(int i=0;i<1000;i++){
stageOne();
stageTwo();

}
}

public void main(){

System.out.println("Starting.....");
long start=System.currentTimeMillis();
//process();
Thread t1=new Thread(new Runnable() {

@Override
public void run() {
process();

}
}) ;

Thread t2=new Thread(new Runnable() {

@Override
public void run() {
process();

}
}) ;
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end=System.currentTimeMillis();
System.out.println("time taken"+(end-start));
System.out.println("List1:"+al1.size()+"List2:"+al2.size());
int a=r.nextInt(100);
}


}

Now the lock is with 2 diffrent objects ,obj1 n obj2 ...so now two threads can enter both the synchronized blocks individually. But no 2 threads can enter the synchronized block.

Now the time taken is 2000 ie 2 sec.

Please leave comment if any doubt



No comments:

Post a Comment