> > |
%META:TOPICINFO{author="CharltonBarreto" date="1099002561" format="1.0" version="1.1"}%
%META:TOPICPARENT{name="JavaLinks"}%
A simple definition of deadlock is that a system is deadlocked
if two or more threads are waiting for two or more locks to to be freed
and the system is such that the locks will never be freed.
The classic example of deadlock is the dining philosophers.
The idea is that there are a bunch of philosophers sitting around a table.
There is a bowl of rice in fron of each philosopher, and a single
chopstick between each philosopher. A philosopher must have two chopsticks
in order to eat. Once a philosopher has eaten, they put down both
chopsticks so that another can eat.
The problem is that if each philosopher picks up the chopstick on the
left, then no philosopher will be able to get to chopsticks, so
they will literally starve because of deadlock
Below are some rules of thumb that help avoid deadlock:
CPU starvation occurs when a thread never becomes the currently
running thread. A thread can starve if it has a lower priority than
the other threads and it never becomes the current thread. CPU
starvation is usually a scheduling issue that occurs because the
scheduler does not increase the priority of a thread that has not run
on the CPU.
Lock starvation occurs when a thread becomes the currently running
thread, but the thread never obtains a lock it needs because another
thread is holding the lock.
Lock starvation is rare, each of the points must be true:
More than one thread must be trying to acquire the same lock.
The intermediate results during lock contention are of interest.
If we are only interested in the final results, then we don't really
care if some of the threads are starved of the lock. Eventually all
the threads will get the lock, and we will get our results.
The threads must have the same priority.
A round-robin scheduler must be controlling the threads.
If the threads are not under a round-robin scheduler, then we will
have CPU starvation, not lock starvation.
We get lock starvation because:
Lock acquisitions do not queue -
If thread is attempting to acquire a lock, it does not check
to see if another thread has tried to acquire the lock and failed.
When a lock is released, the current thread may or may
not continue to be the current thread.
The Java Specification, section 17.12 says that Thread priorities are
a preference:
Every thread has a priority. When there is competition for processing
resources, threads with higher priority are generally executed in
preference to threads with lower priority. Such preference is not,
however, a guarantee that the highest priority thread will always be
running, and thread priorities cannot be used to reliably implement
mutual exclusion.
So, be careful about using priorities.
Another subtle problem is priority inversion, for which I need to
find a good description.
In Swing, components should only be accessed from the
event-dispatching thread.
Resourced
Javasoft Swing Tutorial: Threads and Swing
ArticleIndex in the Swing Connection contains a few articles about Threads
and Swing.
Below are some common thread code fragments that appear over and over again.
In an applet, the code below will start a thread
public void start() {
if (_plotThread == null) {
_plotThread = new Thread(this, "Plot");
_plotThread.start();
}
}
If the thread is null, then either the thread was never
started, or started and stopped. If the thread is null,
we create a new thread and start it. If the thread is not
null in an applet, then we have already started the
thread
public void stop () {
_plotThread = null;
}
We set the thread to null here, but we could just call
_plotThread.stop(). The
Javasoft Thread tutorial
says that stopping a thread is rather
drastic, if the thread is doing something critical, then the
applet might be left in an inconsistant state. Calling stop on a thread
can be somewhat like hitting Control-C on a program -
the program might not cleanup properly before exiting.
Applets that use threads should implement the stop()
method so that when the user moves to another page the applet stops.
This is especially important for threads that produce sound or consume
cpu cycles. See the
Javasoft tutorial applet checklist
for more information.
public void run () {
while (Thread.currentThread() == _plotThread) {
repaint();
try {
Thread.sleep(1000);
} catch (InterruptedException e){
}
}
Here, we check to see if the _plotThread has been set to
null by stop(). If it is not null, then we
call repaint, and sleep for one second.
When we sleep, other threads can run.
-- CharltonBarreto - 27 Jun 2004 |