The earlier support provided by JDK 1.1 to manage threads using suspend()
, resume()
and stop()
are no more relevant since they are deprecated. The suspend method is deprecated because when a thread which has lock is suspended, it causes the other threads to wait.
Similarly
stop
method is also deprecated, since it can cause data corruption because of immediate release of locks while the atomic calculations are in progress.
The new or modern way of suspending, resuming and stopping threads is using
wait()
and
notify()
methods of the
Object
. The below example demonstrates this.
Suspend Threads Using Wait And Notify
class TwentyTwenty
{
public static void main(String arg[])
{
PinchHitter dhoni = new PinchHitter("Dhoni");
PinchHitter yuvi = new PinchHitter("Yuvi");
try
{
Thread.sleep(1000);
dhoni.stopHitting();
System.out.println("Dhoni Hitting Stopped");
Thread.sleep(1000);
dhoni.startHitting();
System.out.println("Dhoni Hitting Started");
yuvi.stopHitting();
System.out.println("Yuvi Hitting Stopped");
Thread.sleep(1000);
yuvi.startHitting();
System.out.println("Yuvi Hitting Started");
}
catch(InterruptedException e)
{
System.out.println("Twenty Twenty cancelled");
}
try
{
System.out.println("Waiting for match to finish");
dhoni.t.join();
yuvi.t.join();
}
catch(InterruptedException e)
{
System.out.println("Twenty Twenty cancelled");
}
System.out.println("Twenty Twenty Innings Completed.");
}
}
class PinchHitter implements Runnable
{
String hitterName;
Thread t;
boolean takeRest;
PinchHitter(String hitterName)
{
this.hitterName = hitterName;
t = new Thread(this, hitterName);
System.out.println("Pinch Hitter Padded up and ready: " + t);
takeRest = false;
t.start();
}
public void run()
{
try
{
for(int i = 20; i > 0; i--)
{
System.out.println(hitterName + " : " + i);
Thread.sleep(200);
synchronized(this)
{
while(takeRest)
{
wait();
}
}
}
}
catch(InterruptedException e)
{
System.out.println(hitterName + " interrupted.");
}
System.out.println(hitterName + " done hitting.");
}
synchronized void stopHitting()
{
takeRest = true;
}
synchronized void startHitting()
{
takeRest = false;
notify(); // LINE X
}
}
OUTPUTPinch Hitter Padded up and ready: Thread[Dhoni,5,main]
Pinch Hitter Padded up and ready: Thread[Yuvi,5,main]
Dhoni : 20
Yuvi : 20
Dhoni : 19
Yuvi : 19
Dhoni : 18
Yuvi : 18
Dhoni : 17
Yuvi : 17
Dhoni : 16
Yuvi : 16
Dhoni Hitting Stopped
Yuvi : 15
Yuvi : 14
Yuvi : 13
Yuvi : 12
Yuvi : 11
Dhoni Hitting Started
Yuvi Hitting Stopped
Dhoni : 15
Dhoni : 14
Dhoni : 13
Dhoni : 12
Dhoni : 11
Yuvi Hitting Started
Waiting for match to finish
Yuvi : 10
Dhoni : 10
Yuvi : 9
Dhoni : 9
Yuvi : 8
Dhoni : 8
Yuvi : 7
Dhoni : 7
Yuvi : 6
Dhoni : 6
Yuvi : 5
Dhoni : 5
Yuvi : 4
Dhoni : 4
Yuvi : 3
Dhoni : 3
Yuvi : 2
Dhoni : 2
Yuvi : 1
Dhoni : 1
Yuvi done hitting.
Dhoni done hitting.
Twenty Twenty Innings Completed.
DESCRIPTIONAs you can see here, we have created two threads which are paused and started using the wait()
and notify()
method. When the stopHitting
method is called, the takeRest
flag is set to true
, which causes the thread to go into wait
mode. When startHitting
method is called, the takeRest
flag is set to false
and the notify
method is called. This causes the thread to resume its work.
Also observe that we are calling the join()
method in the main thread, so that it waits until the two threads complete their work.
THINGS TO TRY
- DOWNLOAD AND TRY THIS LOCALLY - Remove the
notify()
method at LINE X
and see that the thread never resumes since notify
is never called, so it continues to wait.
- Instead of simple
wait
, try wait
with timeout of 500
i.e. wait(500)
and see that the thread resumes even before we call the startHitting
/notify
methods.
Points to note:
- Similar program written using the deprecated methods
suspend()
, resume()
and stop()
would be much smaller but it is risky since it can cause serious system failures.
- Writing the pause, stop and resume functionality using the
boolean
flags, synchronized
methods and wait/notify
mechanism is safer and failure proof, even if it means writing extra code.