Java Reference
In-Depth Information
Thread started...
Going to sleep...
Going to sleep...
Going to sleep...
Suspended...
Resumed...
Going to sleep...
Going to sleep...
Going to sleep...
Thread stopped...
Note that you have two instance variables for the
StopSuspendResume
class. The
suspended
instance variable is
not declared
volatile
. It is not necessary to declare it
volatile
because it is always accessed inside a
synchronized
method/block. The following code in the
run()
method is used to implement the suspend and resume features:
synchronized (this) {
while (suspended) {
System.out.println("Suspended...");
this.wait();
System.out.println("Resumed...");
}
}
When the
suspended
instance variable is set to
true
, the thread calls the
wait()
method on itself to wait. Note
the use of the
synchronized
block. It uses
this
as the object to synchronize. This is the reason that you can call
this.wait()
inside the
synchronized
block because you have obtained the lock on
this
object before entering the
synchronized
block. Once the
this.wait()
method is called, the thread releases the lock on
this
object and keeps
waiting in the wait set until another thread calls the
resumeThread()
method to notify it. I also use the
this.notify()
method call inside the
stopThread()
method because if the thread is suspended when the
stopThread()
method is
called, the thread will not stop; rather, it will remain suspended.
The thread in this example sleeps for only one second in its
run()
method. Suppose your thread sleeps for an
extended period. In such a case, calling the
stopThread()
method will not stop the thread immediately because the
thread will stop only when it wakes up and checks its
keepRunning
instance variable value in its next loop iteration.
In such cases, you can use the
interrupt()
method inside the
stopThread()
method to interrupt sleeping/waiting
threads, and when
InterruptedException
is thrown, you need to handle it appropriately.
If you use the technique used in Listing 6-25 to stop a thread, you may run into problems in some situations. The
while-loop inside the
run()
method depends on the
keepRunning
instance variable, which is set in the
stopThread()
method. The example in this listing is simple. It is just meant to demonstrate the concept of how to stop, suspend,
and resume a thread. Suppose inside the
run()
method, your code waits for other resources like calling a method
someBlockingMethodCall()
as shown:
while (keepRunning) {
try {
someBlockingMethodCall();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}