Synchronization in Java
Synchronization in Java
Types of Synchronization
There are two types of synchronization
1. Process Synchronization
2. Thread Synchronization
Here, we will discuss only thread synchronization.
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
23. }
24. class MyThread2 extends Thread{
25. Table t;
26. MyThread2(Table t){
27. this.t=t;
28. }
29. public void run(){
30. t.printTable(100);
31. }
32. }
33.
34. class Use{
35. public static void main(String args[]){
36. Table obj = new Table();//only one object
37. MyThread1 t1=new MyThread1(obj);
38. MyThread2 t2=new MyThread2(obj);
39. t1.start();
40. t2.start();
41. }
42. }
Output: 5
100
10
200
15
300
20
400
25
500
6.
try{
7.
Thread.sleep(400);
8.
}catch(Exception e){System.out.println(e);}
9.
}
10.
11. }
12. }
13.
14. class MyThread1 extends Thread{
15. Table t;
16. MyThread1(Table t){
17. this.t=t;
18. }
19. public void run(){
20. t.printTable(5);
21. }
22.
23. }
24. class MyThread2 extends Thread{
25. Table t;
26. MyThread2(Table t){
27. this.t=t;
28. }
29. public void run(){
30. t.printTable(100);
31. }
32. }
33.
34. class Use{
35. public static void main(String args[]){
36. Table obj = new Table();//only one object
37. MyThread1 t1=new MyThread1(obj);
38. MyThread2 t2=new MyThread2(obj);
39. t1.start();
40. t2.start();
41. }
42. }
Output: 5
10
15
20
25
100
200
300
400
500
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.
25.
26. }
27. class MyThread2 extends Thread{
28. Table t;
29. MyThread2(Table t){
30. this.t=t;
31. }
32. public void run(){
33. t.printTable(100);
34. }
35. }
36.
37. class Use{
38. public static void main(String args[]){
39. Table obj = new Table();//only one object
40. MyThread1 t1=new MyThread1(obj);
41. MyThread2 t2=new MyThread2(obj);
42. t1.start();
43. t2.start();
44. }
45. }
Output:5
10
15
20
25
100
200
300
400
500
12.
}
13. }
14. }//end of the method
15. }
16.
17. class Use{
18. public static void main(String args[]){
19. final Table obj = new Table();//only one object
20.
21. Thread t1=new Thread(){
22. public void run(){
23. obj.printTable(5);
24. }
25. };
26. Thread t2=new Thread(){
27. public void run(){
28. obj.printTable(100);
29. }
30. };
31.
32. t1.start();
33. t2.start();
34. }
35. }
Output:5
10
15
20
25
100
200
300
400
500
Static synchronization
If you make any static method as synchronized, the lock will be on the class not on
object.
16. }
17. }
18.
19. class MyThread2 extends Thread{
20. public void run(){
21. Table.printTable(10);
22. }
23. }
24.
25. class MyThread3 extends Thread{
26. public void run(){
27. Table.printTable(100);
28. }
29. }
30.
31.
32.
33.
34. class MyThread4 extends Thread{
35. public void run(){
36. Table.printTable(1000);
37. }
38. }
39.
40. class Use{
41. public static void main(String t[]){
42. MyThread1 t1=new MyThread1();
43. MyThread2 t2=new MyThread2();
44. MyThread3 t3=new MyThread3();
45. MyThread4 t4=new MyThread4();
46. t1.start();
47. t2.start();
48. t3.start();
49. t4.start();
50. }
51. }
Output: 1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
8.
}catch(Exception e){}
9.
}
10. }
11. }
12.
13. public class Test {
14. public static void main(String[] args) {
15.
16.
Thread t1=new Thread(){
17.
public void run(){
18.
Table.printTable(1);
19.
}
20.
};
21.
22.
Thread t2=new Thread(){
23.
public void run(){
24.
Table.printTable(10);
25.
}
26.
};
27.
28.
Thread t3=new Thread(){
29.
public void run(){
30.
Table.printTable(100);
31.
}
32.
};
33.
34.
Thread t4=new Thread(){
35.
public void run(){
36.
Table.printTable(1000);
37.
}
38.
};
39.
t1.start();
40.
t2.start();
41.
t3.start();
42.
t4.start();
43.
44. }
45. }
Output: 1
2
3
4
5
6
7
8
9
10
10
20
30
40
50
60
70
80
90
100
100
200
300
400
500
600
700
800
900
1000
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
5. }
Deadlock:
Deadlock can occur in a situation when a thread is waiting for an object lock, that is
acquired by another thread and second thread is waiting for an object lock that is
acquired by first thread. Since, both threads are waiting for each other to release
the lock, the condition is called deadlock.
26.
try { Thread.sleep(100);} catch (Exception e) {}
27.
28.
synchronized (resource1) {
29.
System.out.println("Thread 2: locked resource 1");
30.
}
31.
}
32.
}
33.
};
34.
35.
36.
t1.start();
37.
t2.start();
38. }
39. }
40.
Output: Thread 1: locked resource 1
Thread 2: locked resource 2
wait()
notify()
notifyAll()
1) wait() method
Causes current thread to release the lock and wait until either another thread invokes
the notify() method or the notifyAll() method for this object, or a specified amount of
time has elapsed.
The current thread must own this object's monitor, so it must be called from the
synchronized method only otherwise it will throw exception.
Method
Description
InterruptedException
time.
2) notify() method
Wakes up a single thread that is waiting on this object's monitor. If any threads are
waiting on this object, one of them is chosen to be awakened. The choice is arbitrary
and occurs at the discretion of the implementation. Syntax:
public final void notify()
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor. Syntax:
public final void notifyAll()
sleep()
methods
completed.
class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
6.
7. if(this.amount<amount){
8. System.out.println("Less balance; waiting for
9. try{wait();}catch(Exception e){}
10. }
11. this.amount-=amount;
12. System.out.println("withdraw completed...");
13. }
14.
15. synchronized void deposit(int amount){
16. System.out.println("going to deposit...");
17. this.amount+=amount;
18. System.out.println("deposit completed... ");
19. notify();
20. }
21. }
22.
23. class Test{
24. public static void main(String args[]){
25. final Customer c=new Customer();
26. new Thread(){
27. public void run(){c.withdraw(15000);}
28. }.start();
29. new Thread(){
30. public void run(){c.deposit(10000);}
31. }.start();
32.
33. }}
deposit...");
Interrupting a Thread:
If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked),
calling the interrupt() method on the thread, breaks out the sleeping or waiting
state throwing InterruptedException. If the thread is not in the sleeping or waiting
state, calling the interrupt() method performs normal behaviour and doesn't
interrupt the thread but sets the interrupt flag to true. Let's first see the methods
provided by the Thread class for thread interruption.
4
5
According to Sun Microsystems, Java monitors are reentrant means java thread
can reuse the same monitor for different synchronized methods if method is called
from the method.
Let's understand the java reentrant monitor by the example given below:
1. class Reentrant {
2.
public synchronized void m() {
3.
n();
4.
System.out.println("this is m() method");
5.
}
6.
public synchronized void n() {
7.
System.out.println("this is n() method");
8.
}
9. }
In this class, m and n are the synchronized methods. The m() method internally calls
the n() method.
Now let's call the m() method on a thread. In the class given below, we are creating
thread using annonymous class.
1. class ReentrantExample{
2. public static void main(String args[]){
3. final Reentrant re=new Reentrant();
4.
5. Thread t1=new Thread(){
6. public void run(){
7. re.m();//calling method of Reentrant class
8. }
9. };
10. t1.start();
11. }}
Output: this is n() method
this is m() method