Trail: Essential Java Classes
|
Lesson: Doing Two or More Tasks At Once: Threads
|
|
Synchronizing Threads
So far, this lesson has contained examples with independent,
asynchronous threads. That is, each thread contained all of the
data and methods required for its execution and didn't require
any outside resources or methods. In addition, the threads in
those examples ran at their own pace without concern over the
state or activities of any other concurrently running threads.
However, there are many interesting situations where separate,
concurrently running threads do share data and must consider
the state and activities of other threads. One such set of
programming situations are known as producer/consumer scenarios
where the producer generates a stream of data which then is consumed
by a consumer.
For example, imagine a Java application where one thread
(the producer) writes data to a file while a second thread (the consumer)
reads data from the same file. Or, as you type characters on the keyboard,
the producer thread places key events in an event queue and the consumer
thread reads the events from the same queue. Both of these examples use
concurrent threads that share a common resource: the first shares a file,
the second shares an event queue.
Because the threads share a common resource, they must be synchronized in
some way.
This lesson teaches you about Java thread
synchronization through a simple
producer/consumer example.
The code segments within a program that access the same object from
separate, concurrent threads are called critical sections.
In the Java
language, a critical section can be a block or a method and are
identified with the synchronized keyword.
The Java platform then
associates a lock with every object that has synchronized code.
This section investigates the code in CubbyHole's
put and get methods that helps the
Producer and Consumer coordinate their
activities.
If you write a program in which several concurrent threads are competing
for resources, you must take precautions to ensure fairness. A system is
fair when each thread gets enough access to limited resource to make
reasonable progress. A fair system prevents starvation
and deadlock. Starvation occurs when one or more threads in
your program is blocked from gaining access to a resource and thus cannot make
progress. Deadlock is the ultimate form of starvation; it occurs when two
or more threads are waiting on a condition that cannot be satisfied.
Deadlock most often occurs when two (or more) threads are each waiting
for the other(s) to do something.
This section uses the dining philosophers problem to illustrate
deadlock. It also discusses ways you can prevent deadlock.
|