Showing posts with label synchronized method. Show all posts
Showing posts with label synchronized method. Show all posts

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