Vous êtes sur la page 1sur 13

Handout

All information, including graphical representations, etc provided in this presentation is for exclusive use of current Globsyn
finishing school students and faculty. No part of the document may be reproduced in any form or by any means, electronic or
otherwise, without written permission of the owner.
Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?

Why is Thread.stop deprecated?

Because it is inherently unsafe. Stopping a thread causes it to unlock all the


monitors that it has locked. (The monitors are unlocked as the ThreadDeath
exception propagates up the stack.) If any of the objects previously protected by
these monitors were in an inconsistent state, other threads may now view these
objects in an inconsistent state. Such objects are said to be damaged. When
threads operate on damaged objects, arbitrary behavior can result. This beha
vior may be subtle and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no
warning that his program may be corrupted. The corruption can manifest itself at
any time after the actual damage occurs, even hours or days in the future.

Couldn't I just catch the ThreadDeath exception and fix the damaged
object?

In theory, perhaps, but it would vastly complicate the task of writing correct
multithreaded code. The task would be nearly insurmountable for two reasons:

A thread can throw a ThreadDeath exception almost anywhere. All synchronized


methods and blocks would have to be studied in great detail, with this in mind. A
thread can throw a second ThreadDeath exception while cleaning up from the
first (in the catch or finally clause). Cleanup would have to repeated till it
succeeded. The code to ensure this would be quite complex.

In sum, it just isn't practical.

What about Thread.stop(Throwable)?

In addition to all of the problems noted above, this method may be used to
generate exceptions that its target thread is unprepared to handle (including
checked exceptions that the thread could not possibly throw, were it not for this
method). For example, the following method is behaviorally identical to Java's
throw operation, but circumvents the compiler's attempts to guarantee that the
calling method has declared all of the checked exceptions that it may throw:

static void sneakyThrow(Throwable t) {


Thread.currentThread().stop(t);
}

3 Version 1.00
What should I use instead of Thread.stop?

Most uses of stop should be replaced by code that simply modifies some variable
to indicate that the target thread should stop running. The target thread should
check this variable regularly, and return from its run method in an orderly fashion
if the variable indicates that it is to stop running. (This is the approach that
JavaSoft's Tutorial has always recommended.) To ensure prompt communication
of the stop-request, the variable must be volatile (or access to the variable must
be synchronized). For example, suppose your applet contains the following start,
stop and run methods:

private Thread blinker;

public void start() {


blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
Thread thisThread = Thread.currentThread();
while (true) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's stop and run
methods with:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.current Thread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
} catch (InterruptedException e){
}

4 Version 1.00
repaint();
}
}

How do I stop a thread that waits for long periods (e.g., for input)?

That's what the Thread.interrupt method is for. The same "state based" signaling
mechanism shown above can be used, but the state change (blinker = null, in the
previous example) can be followed by a call to Thread.interrupt, to interrupt the
wait:

public void stop() {


Thread moribund = waiter;
waiter = null;
moribund.interrupt();
}

For this technique to work, it's critical that any method that catches an interrup t
exception and is not prepared to deal with it immediately reasserts the exception.
We say reasserts rather than rethrows, because it is not always possible to
rethrow the exception. If the method that catches the InterruptedException is not
declared to throw this (checked) exception, then it should "reinterrupt itself" with
the following incantation:

Thread.currentThread().interrupt();

This ensures that the Thread will reraise the InterruptedException as soon as it is
able.

What if a thread doesn't respond to Thread.interrupt?

In some cases, you can use application specific tricks. For example, if a thread is
waiting on a known socket, you can close the socket to cause the thread to
return immediately. Unfortunately, there really isn't any technique that works in
general. It should be noted that in all situations where a waiting thread doesn't
respond to Thread.interrupt, it wouldn't respond to Thread.stop either. Such
cases include deliberate denial-of-service attacks, and I/O operations for which
thread.stop and thread.interrupt do not work properly.

Why are Thread.suspend and Thread.resume deprecated?

Thread.suspend is inherently deadlock-prone. If the target thread holds a lock on


the monitor protecting a critical system resource when it is suspended, no thread

5 Version 1.00
can access this resource until the target thread is resumed. If the thread that
would resume the target thread attempts to lock this monitor prior to calling
resume, deadlo ck results. Such deadlocks typically manifest themselves as
"frozen" processes.

What should I use instead of Thread.suspend and Thread.resume?

As with Thread.stop, the prudent approach is to have the "target thread" poll a
variable indicating the desired state of the thread (active or suspended). When
the desired state is suspended, the thread waits using Object.wait. When the
thread is resumed, the target thread is notified using Object.notify.

For example, suppose your applet contains the following mousePressed event
handler, which toggles the state of a thread called blinker:

private boolean threadSuspended;


Public void mousePressed(MouseEvent e) {
e.consume();
if (threadSuspended)
blinker.resume();
else
blinker.suspend(); // DEADLOCK-PRONE!
threadSuspended = !threadSuspended;
}

You can avoid the use of Thread.suspend and Thread.resume by replacing the
event handler above with:

public synchronized void mousePressed(MouseEvent e) {


e.consume();
threadSuspended = !threadSuspended;
if (!threadSuspended)
notify();
}
and adding the following code to the "run loop":
synchronized(this) {
while (threadSuspended)
wait();
}

The wait method throws the InterruptedException, so it must be inside a try ...
catch clause. It's fine to put it in the same clause as the sleep. The check should

6 Version 1.00
follow (rather than precede) the sleep so the window is immediately repainted
when the the thread is "resumed." The resulting run method follows:

public void run() {


while (true) {
try {
Thread.currentThread().sleep(interval);
synchronized(this) {
while (threadSuspended)
wait();
}
} catch (InterruptedException e){
}
repaint();
}
}

Note that the notify in the mousePressed method and the wait in the run method
are inside synchronized blocks. This is required by the language, and ensures
that wait and notify are properly serialized. In practical terms, this eliminates
race conditions that could cause the "suspended" thread to miss a notify and
remain suspended indefinitely.

While the cost of synchronization in Java is decreasing as the platform matures, it


will never be free. A simple trick can be used to remove the synchronization that
we've added to each iteration of the "run loop." The synchronized block that was
added is replaced by a slightly more complex piece of code that enters a
synchronized block only if the thread has actually been suspended:

if (threadSuspended) {
synchronized(this) {
while (threadSuspended)
wait();
}
}
In the absence of explicit synchronization, threadSuspended must be made
volatile to ensure prompt communication of the suspend-request.

The resulting run method is:

private boolean volatile threadSuspended;


public void run() {
while (true) {

7 Version 1.00
try {
Thread.currentThread().sleep(interval);
if (threadSuspended) {
synchronized(this) {
while (threadSuspended)
wait();
}
}
} catch (InterruptedException e){
}
repaint();
}
}

Can I combine the two techniques to produce a thread that may be safely
"stopped" or "suspended"?

Yes; it's reasonably straightforward. The one subtlety is that the target thread
may already be suspended at the time that another thread tries to stop it. If the
stop method merely sets the state variable (blinker) to null, the target thread will
remain suspended (waiting on the monitor), rather than exiting gracefully as it
should. If the applet is restarted, multiple threads could end up waiting on the
monitor at the same time, resulting in erratic behavior.

To rectify this situation, the stop method must ensure that the target thread
resumes immediately if it is suspended. Once the target thread resumes, it must
recognize immediately that it has been stopped, and exit gracefully. Here's how
the resulting run and stop methods look:

public void run() {


Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
thisThread.sleep(interval);
synchronized(this) {
while (threadSuspended && blinker==thisThread)
wait();
}
} catch (InterruptedException e){
}
repaint();
}
}

8 Version 1.00
public synchronized void stop() {
blinker = null;
notify();
}

If the stop method calls Thread.interrupt, as described above, it needn't call


notify as well, but it still must be synchronized. This ensures that the target
thread won't miss an interrupt due to a race condition.

What about Thread.destroy?

Thread.destroy has never been implemented. If it were implemented, it would be


deadlock-prone in the manner of Thread.suspend. (In fact, it is roughly
equivalent to Thread.suspend without the possibility of a subsequent
Thread.resume.) We are not implementing it at this time, but neither are we
deprecating it (forestalling its implementation in future). While it would certainly
be deadlock prone, it has been argued that there may be circumstances where a
program is willing to risk a deadlock rather than exit outright.

Why is Runtime.runFinalizersOnExit deprecated?

Because it is inherently unsafe. It may result in finalizers being called on live


objects while other threads are concurrently manipulating those objects, resulting
in erratic behavior or deadlock. While this problem could be prevented if the class
whose objects are being finalized were coded to "defend against" this call, most
programmers do not defend against it. They assume that an object is dead at the
time that its finalizer is called.

Further, the call is not "thread-safe" in the sense that it sets a VM-global flag.
This forces every class with a finalizer to defend against the finalization of live
objects!

What are three ways in which a thread can enter the waiting state?
Or
What are different ways in which a thread can enter the waiting state?

A thread can enter the waiting state by the following ways:

1. Invoking its sleep() method,


2. By blocking on I/O
3. By unsuccessfully attempting to acquire an object's lock
4. By invoking an object's wait() method.

9 Version 1.00
5. It can also enter the waiting state by invoking its (deprecated) suspend()
method.

What is the difference between yielding and sleeping?

When a task invokes its yield() method, it returns to the ready state, either from
waiting, running or after its creation. When a task invokes its sleep() method, it
returns to the waiting state from a running state.

How to create multithreaded program? Explain different ways of using


thread? When a thread is created and started, what is its initial state?
Or
Extending Thread class or implementing Runnable Interface. Which is
better?

You have two ways to do so. First, making your class "extends" Thread class. The
other way is making your class implement "Runnable" interface. The latter is
more advantageous, cause when you are going for multiple inheritance, then only
interface can he lp. . If you are already inheriting a different class, then you have
to go for Runnable Interface. Otherwise you can extend Thread class. Also, if you
are implementing interface, it means you have to implement all methods in the
interface. Both Thread class and Runnable interface are provided for convenience
and use them as per the requirement. But if you are not extending any class,
better extend Thread class as it will save few lines of coding. Otherwise
performance wise, there is no distinguishable difference. A thread is in the ready
state after it has been created and started.

What is mutual exclusion? How can you take care of mutual exclusion
using Java threads?

Mutual exclusion is a phenomenon where no two processes can access critical


regions of memory at the same time. Using Java multithreading we can arrive at
mutual exclusion. For mutual exclusion, you can simply use the synchronized
keyword and explicitly or implicitly provide an Object, any Object, to synchronize
on. The synchronized keyword can be applied to a class, to a method, or to a
block of code.

There are several methods in Java used for communicating mutually exclusive
threads such as wait( ), notify( ), or notifyAll( ). For example, the notifyAll( )
method wakes up all threads that are in the wait list of an object.

10 Version 1.00
What is the difference between preemptive scheduling and time slicing?

Under preemptive scheduling, the highest priority task executes until it enters
the waiting or dead states or a higher priority task comes into existence. Under
time slicing, a task executes for a predefined slice of time and then re-enters the
pool of ready tasks. The scheduler then determines which task should execute
next, based on priority and other factors.

What invokes a thread's run() method?

After a thread is started, via its start() method of the Thread class, the JVM
invokes the thread's run() method when the thread is initially executed.

What is the purpose of the wait(), notify(), and notifyAll() methods?

The wait(), notify() and notifyAll() methods are used to provide an efficient way
for thread intercommunication.

What is thread? What are the high-level thread states?


Or
What are the states associated in the thread?

A thread is an independent path of execution in a system. The high- level thread


states are ready, running, waiting and dead.

What is deadlock?

When two threads are waiting for each other and can’t proceed until the first
thread obtains a lock on the other thread or vice versa, the program is said to be
in a deadlock.

How does multithreading take place on a computer with a single CPU?

The operating system's task scheduler allocates execution time to multiple tasks.
By quickly switching between executing tasks, it creates the impression that
tasks execute sequentially.

What are synchronized methods and synchronized statements?

Synchronized methods are methods that are used to control access to an object.
A thread only executes a synchronized method after it has acquired the lock for
the method's object or class. Synchronized statements are similar to
synchronized methods. A synchronized statement can only be executed after a

10 Version 1.00
thread has acquired the lock for the object or class referenced in the
synchronized statement.

Can Java object be locked down for exclusive use by a given thread?
Or
What happens when a thread cannot acquire a lock on an object?

Yes. You can lock an object by putting it in a "synchronized" block. The locked
object is inaccessible to any thread other than the one that explicitly claimed it. If
a thread attempts to execute a synchronized method or synchronized statement
and is unable to acquire an object's lock, it enters the waiting state until the lock
becomes available.

What’s the difference between the methods sleep() and wait()?

The sleep method is used when the thread has to be put aside for a fixed amount
of time. Ex: sleep(1000), puts the thread aside for exactly one second. The wait
method is used to put the thread aside for up to the specified time. It could wait
for much lesser time if it receives a notify() or notifyAll() call. Ex: wait(1000),
causes a wait of up to one second. The method wait() is defined in the Object
and the method sleep() is defined in the class Thread.

What is the difference between process and thread?

A thread is a separate path of execution in a program. A Process is a program in


execution.

What is daemon thread and which method is used to create the daemon
thread?

Daemon threads are threads with low priority and runs in the back ground doing
the garbage collection operation for the java runtime system. The setDaemon()
method is used to create a daemon thread. These threads run without the
intervention of the user. To determine if a thread is a daemon thread, use the
accessor method isDaemon()

When a standalone application is run then as long as any user threads are active
the JVM cannot terminate, otherwise the JVM terminates along with any daemon
threads which might be active. Thus a daemon thread is at the mercy of the
runtime system. Daemon threads exist only to serve user threads.

11 Version 1.00
What do you understand by Synchronization?
Or
What is synchronization and why is it important?
Or
Describe synchronization in respect to multithreading?
Or
What is synchronization?

With respect to multithreading, Synchronization is a process of controlling the


access of shared resources by the multiple threads in such a manner that only
one thread can access a particular resource at a time. In non synchronized
multithreaded application, it is possible for one thread to modify a shared object
while another thread is in the process of using or updating the object's value.
Synchronization prevents such type of data corruption which may otherwise lead
to dirty reads and significant errors.

E.g. synchronizing a function:


public synchronized void Method1 () {
// method code.
}
E.g. synchronizing a block of code inside a function:
public Method2 (){
synchronized (this) {
// synchronized code here.
}
}

When you will synchronize a piece of your code?

When you expect that your shared code will be accessed by different threads and
these threads may change a particular data causing data corruption, then they
are placed in a synchronized construct or a synchronized method.

Why would you use a synchronized block vs. synchronized method?

Synchronized blocks place locks for shorter periods than synchronized methods.

What is an object's lock and which objects have locks?

Answer: An object's lock is a mechanism that is used by multiple threads to


obtain synchronized access to the object. A thread may execute a synchronized
method of an object only after it has acquired the object's lock. All objects and
classes have locks. A class's lock is acquired on the class's Class object.

12 Version 1.00
Can a lock be acquired on a class?

Yes, a lock can be acquired on a class. This lock is acquired on the class's Class
object.

What state does a thread enter when it terminates its processing?

When a thread terminates its processing, it enters the dead state.

How would you implement a thread pool?

public class ThreadPool implements ThreadPoolInt

This class is an generic implementation of a thread pool, which takes the


following input a) Size of the pool to be constructed b) Name of the class which
implements Runnable and constructs a thread pool with active threads that are
waiting for activation. Once the threads have finished processing they come back
and wait once again in the pool.

This thread pool engine can be locked i.e. if some internal operation is performed
on the pool then it is preferable that the thread engine be locked. Locking
ensures that no new threads are issued by the engine. However, the currently
executing threads are allowed to continue till they come back to the passivePool.

Is there a separate stack for each thread in Java?

Yes. Every thread maintains its own separate stack, called Runtime Stack but
they share the same memory. Elements of the stack are the method invocations,
called activation records or stack frame. The activation record contains pertinent
information about a method like local variables.

13 Version 1.00

Vous aimerez peut-être aussi