Threads in Java: A Tutorial Introduction
Threads in Java: A Tutorial Introduction
a tutorial introduction
(revision 7)
Christian Ratliff [email protected] Senior Technology Architect Core Libraries Group, DeLorme 28 August 2002
Demo
SerialPrime.java
What is a thread?
Free Online Dictionary of Computing (FOLDOC) Sharing a single CPU between multiple tasks (or "threads") in a way designed to minimize the time required to switch tasks. This is accomplished by sharing as much as possible of the program execution environment between the different tasks so that very little state needs to be saved and restored when changing tasks.
Copyright 2002, DeLorme
maintain responsiveness of an application during a long running task. To enable cancellation of separable tasks. Some problems are intrinsically parallel. To monitor status of some resource (DB). Some APIs and systems demand it: Swing. To take advantage of multiple processors. It looks great on your resume.
Copyright 2002, DeLorme
GC
critical concepts:
At
RAM
run
run
main main
run
main
java.lang.Runnable
An
adapter which enables any given class to operate as a thread. Requires one method be implemented:
public void run()
Most
common method for adding threads to an application. Prevents certain thread operations (e.g. Thread.isAlive()).
Copyright 2002, DeLorme
Demo
counter/CounterThread0.java
java.lang.Thread
A
base class with maximum threading functionality. While less common, it is far more powerful. Forces the focus of your class to its threadedness. Minimum requirements are like Runnable:
public void run()
Demo
counter/CounterThread1.java
Demo
counter/CounterThread2.java
Cooperative Multithreading
By
adding a Thread.yield() call to the subthread and the main, all 50 values were fetched. Success depends on careful cooperation between each thread. This is not a safe option.
Wizards:
Copyright 2002, DeLorme
only safe mechanism is through locking. There are many kinds of locks:
busy-wait-flag, semaphore, mutex, etc
They Java
monitors
Wizards:
Copyright 2002, DeLorme
synchronized
Monitors
basis. Each method on an object which accesses protected resources is marked synchronized.
The
monitor is a fence around the object. Each synchronized method is a gate in that fence.
Copyright 2002, DeLorme
Inside Monitors
addPrimeToCache PrimeCache
run
primes
maxPrime
main
isPrime
Inside Monitors
addPrimeToCache PrimeCache
primes
maxPrime
main
run isPrime
Inside Monitors
addPrimeToCache PrimeCache
primes
maxPrime
main
isPrime
Inside Monitors
addPrimeToCache PrimeCache
primes
maxPrime
main
isPrime
Inside Monitors
addPrimeToCache PrimeCache
primes
maxPrime
isPrime
Demo
sieve/SieveThread0.java
*SNORE*
WAKE UP! SNACK TIME!
Signalling
of the synchronized attribute alone is not sufficient. If a thread must wait for both access to a resource and a condition to be satisfied, the only obvious option is a busy-wait. There must be a better way!
Use
Signalling
Object.wait() Gives up ownership of the monitor. Blocks until timeout, interruption, or notification. On waking, the thread enters the monitor acquisition phase.
Copyright 2002, DeLorme
Object.notify() Object.notifyAll() Does not give up ownership of the monitor. Wakes an arbitrary, or all, thread(s) blocked on the monitor. No thread preference!
Demo
sieve/SieveThread1.java
Exception Handling
When
an exception is emitted out of the run() method, the thread is terminated. The exception is consumed by the JVM because once Thread.start() is called, the created thread is split from the caller. Java provides a means for dispatching a copy of the exception: ThreadGroup.
java.lang.ThreadGroup
When
a class from ThreadGroup. Override the uncaughtException method, relaying the thread and exception information.
Derive
Copyright 2002, DeLorme
Demo
group/SieveThread.java
Demo
halt/SieveThread.java
An atomic operation permits no interruptions. The JMM promises that 32bit reads and writes are atomic. Any types greater than 32bits in size should be protected with a monitor. No multi-step operation can ever be atomic without the use of a monitor. Fields marked as volatile are always completely flushed at every write (even 64bit ones).
Copyright 2002, DeLorme
In a synchronized block, instructions are not reordered (as-if-serial). This is the same as within try-catch-finally blocks. When another thread is watching the fields of the synchronized block, it perceives nonreordered semantics as well.
Reads and writes of instance fields must act on the same data, even on different CPUs. Exiting a monitor flushs all writes from the variable cache to main memory. Acquiring a monitor forces the JVM to reload any cached variable information. When a thread exits, its cache is flushed to memory.
Copyright 2002, DeLorme
Advanced Topics
Thread
scheduling issues: one-to-one, many-to-one, many-to-many. Thread pooling implementations. Deadlock detection and prevention.