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);
}
}
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 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