Synchronizing Threads
Synchronization in java is the capability to control the access of multiple threads to any
shared resource. When we want to share the resource with multiple threads, we can use the
Java synchronization concept. So there is a need to synchronize the action of multiple threads
and make sure that only one thread can access the resource at a given point in time. This is
implemented using a concept called monitors. Each object in Java is associated with a
monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a
monitor.
4.4.1 Purpose of using synchronization
1. To prevent thread interference
2. To prevent consistency problem
4.4.2 Types of Thread synchronization
There are two types of thread synchronization mutual exclusive and inter-thread
communication.
Mutual Exclusive
Synchronized method.
Synchronized block.
static synchronization.
Cooperation (Inter-thread communication in java)
4.4.3 Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data.
This can be done by three ways in java:
by synchronized method
by synchronized block
by static synchronization
[Link] Synchronized Method
If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource. When a thread
invokes a synchronized method, it automatically acquires the lock for that object and releases
it when the thread completes its task.
Example Program: Without Synchronized Method class Table
{
void printTable(int n)
{//method not synchronized
for(int i=1;i<=5;i++) {
[Link](n*i);
try
{
[Link](400);
}
catch(Exception e){[Link](e);}
}
}
}
class MyThread1 extends Thread
{
Table t;
MyThread1(Table t)
{ this.t=t;
}
public void run()
{
[Link](5);
}
}
class MyThread2 extends Thread
{
Table t;
MyThread2(Table t)
{ this.t=t;
}
public void run()
{
[Link](100);
}
}
class TestSynchronization1
{
public static void main(String args[])
{
Table obj = new Table();//only one object MyThread1 t1=new
MyThread1(obj);
MyThread2 t2=new MyThread2(obj); [Link]();
[Link]();
}
}
Output:
5
100
10
200
15
300
20
400
25
500
Example Program: With Synchronized Method
class Table
{
synchronized void printTable(int n)
{//synchronized method
for(int i=1;i<=5;i++)
{
[Link](n*i);
try
{
[Link](400);
}
catch(Exception e)
{
[Link](e);
}}
} } class MyThread1 extends Thread {
Table t;
MyThread1(Table t)
{
this.t=t;
}
public void run()
{
[Link](5);
}
}
class MyThread2 extends Thread {
Table t;
MyThread2(Table t)
{ this.t=t;
}
public void run()
{
[Link](100);
}
}
public class TestSynchronization2
{
public static void main(String args[])
{
Table obj = new Table();//only one object MyThread1 t1=new
MyThread1(obj);
MyThread2 t2=new MyThread2(obj); [Link]();
[Link]();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
[Link] 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.
Purpose of 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.
Syntax:
synchronized (object reference expression)
{
//code block
}
Example program:
class Table
{
void printTable(int n)
{
synchronized(this)
{//synchronized block
for(int i=1;i<=5;i++)
{
[Link](n*i);
try
{
[Link](400);
}
catch(Exception e)
{
[Link](e);
}
}
}
}//end of the method
}
class MyThread1 extends Thread
{
Table t;
MyThread1(Table t)
{ this.t=t;
}
public void run()
{
[Link](5);
}
}
class MyThread2 extends Thread
{
Table t;
MyThread2(Table t)
{
this.t=t;
}
public void run()
{
[Link](100);
}
}
public class TestSynchronizedBlock1
{
public static void main(String args[])
{
Table obj = new Table();//only one object MyThread1 t1=new
MyThread1(obj);
MyThread2 t2=new MyThread2(obj); [Link]();
Rohini college of Engineering and technology
25 CS8392 Object Oriented Programming
[Link]();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
[Link] Static Synchronization Block
If you make any static method as synchronized, the lock will be on
the class not on object.
Example Program:
class Table
{
synchronized static void printTable(int n)
{
for(int i=1;i<=10;i++)
{
[Link](n*i);
try
{
[Link](400);
}
catch(Exception e){}
}
}
}
class MyThread1 extends Thread
{
public void run()
{
[Link](1);
}
}
class MyThread2 extends Thread
{
public void run()
{
[Link](10);
}
}
class MyThread3 extends Thread
{
public void run()
{
[Link](100);
}
}
class MyThread4 extends Thread
{
public void run()
{
[Link](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()
[Link]();
[Link]();
[Link]();
[Link]();
}
}
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
60008000
9000
10000 7000
4.5 Inter-thread Communication
Polling is a process in which the condition is repeatedly checked. If the condition is
true, appropriate action is taken. This wastes CPU time.
For example, consider the classic queuing problem, where one thread is producing
some data and another is consuming it. To make the problem more interesting, suppose that
the producer has to wait until the consumer is finished before it generates more data. In a
polling system, the consumer would waste many CPU cycles while it waited for the producer
to produce. Once the producer was finished, it would start polling, wasting more CPU cycles
waiting for the consumer to finish, and so on.
To avoid polling, Java includes an elegant interprocess communication mechanism
via the wait( ), notify( ), and notifyAll( ) methods. These methods are implemented as final
methods in Object, so all classes have them. All three methods can be called only from within
a synchronized context.
• wait( ) tells the calling thread to give up the monitor and go to sleep until some
other thread enters the same monitor and calls notify( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of
the threads will be granted access.
The following methods are declared within Object:
final void wait( ) throws InterruptedException
final void notify( )
final void notify All( )
class SimpleWaitNotify {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
// Thread that waits
Thread waiter = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
try {
[Link]("Waiter: waiting...");
[Link](); // release lock and wait
[Link]("Waiter: notified!");
} catch (InterruptedException e) {
[Link]();
}
}
}
});
// Thread that notifies
Thread notifier = new Thread(new Runnable() {
public void run() {
synchronized (lock) {
[Link]("Notifier: sending notify...");
[Link](); // wake up waiter
}
}
});
[Link]();
[Link](500); // give waiter time to start
[Link]();
}
}