You are on page 1of 40

Threads in Java

a tutorial introduction
(revision 7)

Christian Ratliff cratliff@delorme.com Senior Technology Architect Core Libraries Group, DeLorme 28 August 2002

Demo

SerialPrime.java

Copyright 2002, DeLorme

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

Wherefore art thou?


To

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

Threads and Processes


CPU main run Process 1 Process 2 Process 3 Process 4

GC

Copyright 2002, DeLorme

Oh No! Computer Science!!


Some

critical concepts:

non-determinism race condition concurrency parallel scheduling

At

least I am not charging $10,000 a year!

Copyright 2002, DeLorme

Concurrency vs. Parallelism


CPU CPU1 CPU2

Copyright 2002, DeLorme

Concurrency vs. Parallelism


CPU CPU1 main CPU2 main

RAM
run

main run this.count

run

main main

run
main

Copyright 2002, DeLorme

Whatever! How about some code?


In

Java, thread instances come in two varieties:


java.lang.Runnable java.lang.Thread

Copyright 2002, DeLorme

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

Copyright 2002, DeLorme

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()

Copyright 2002, DeLorme

Demo

counter/CounterThread1.java

Copyright 2002, DeLorme

Thread State Diagram


Alive Running new CounterThread1(max); New Thread cntThread.start(); while () { } Runnable Dead Thread run() method returns Blocked

Copyright 2002, DeLorme

Object.wait() Thread.sleep() blocking IO call waiting on a monitor

Demo

counter/CounterThread2.java

Copyright 2002, DeLorme

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

What is the other problem here?

Accessing Shared Resources


The

only safe mechanism is through locking. There are many kinds of locks:
busy-wait-flag, semaphore, mutex, etc
They Java

can offer many differing semantics:


offers one, coherent mechanism: Who invented the monitor? When?

barriers, reader-writer, critical sections, etc

monitors
Wizards:
Copyright 2002, DeLorme

synchronized
Monitors

basis. Each method on an object which accesses protected resources is marked synchronized.
The

are implemented on a per-object

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

Copyright 2002, DeLorme

Inside Monitors
addPrimeToCache PrimeCache

primes

maxPrime

main

run isPrime

Copyright 2002, DeLorme

Inside Monitors
addPrimeToCache PrimeCache

primes

maxPrime

main

isPrime

Copyright 2002, DeLorme

Inside Monitors
addPrimeToCache PrimeCache

primes

maxPrime

main

isPrime

Copyright 2002, DeLorme

Inside Monitors
addPrimeToCache PrimeCache

primes

maxPrime

isPrime

Copyright 2002, DeLorme

Demo

sieve/SieveThread0.java

Copyright 2002, DeLorme

Other uses of synchronized


There

are two additional situations where synchronized may be used:


The synchronized statement may be used in a method to synchronize an arbitrary block of code. A static method may be labeled as synchronized, in which case the monitor it attached to the enclosing class.

Copyright 2002, DeLorme

*SNORE*
WAKE UP! SNACK TIME!

Copyright 2002, DeLorme

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

Copyright 2002, DeLorme

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

Copyright 2002, DeLorme

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.

Copyright 2002, DeLorme

java.lang.ThreadGroup
When

an exception is emitted by the Thread.run method, the method ThreadGroup.uncaughtException is called.

a class from ThreadGroup. Override the uncaughtException method, relaying the thread and exception information.
Derive
Copyright 2002, DeLorme

Demo

group/SieveThread.java

Copyright 2002, DeLorme

Jane, stop this crazy thing!


There

are three ways to halt a thread:


Thread.stop(), Thread.destroy()

The wrong way


Thread.suspend(),

The long way


The

thread tests a control flag in the instance destroy a dependent resource

The pull-the-rug-out way


Thread.interrupt(),

Copyright 2002, DeLorme

Demo

halt/SieveThread.java

Copyright 2002, DeLorme

Three Concurrency Risks


Atomicity

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

Three Concurrency Risks


Ordering

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.

Copyright 2002, DeLorme

Three Concurrency Risks


class Test { static int i = 0; static int j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } } class Test { static int i = 0; static int j = 0; static synchronized void one() { i++; j++; } static synchronized void two() { System.out.println("i=" + i + " j=" + j); }

Copyright 2002, DeLorme

Three Concurrency Risks


class Test { static int i = 0; static int j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } } } class Test { static volatile int i = 0; static volatile int j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); }

Copyright 2002, DeLorme

Three Concurrency Risks


Visibility

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.

Copyright 2002, DeLorme

You might also like