25
COMP 150-CCP COMP 150-CCP Concurrent Programming Concurrent Programming Lecture 8: Java Thread Introduction Dr. Richard S. Hall [email protected] Concurrent programming – February 12, 2008

Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

  • Upload
    others

  • View
    12

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

COMP 150-CCPCOMP 150-CCPConcurrent ProgrammingConcurrent Programming

Lecture 8:Java Thread Introduction

Dr. Richard S. [email protected]

Concurrent programming – February 12, 2008

Page 2: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Java Thread Life CycleJava Thread Life Cycle

An overview of the life cycle of a thread as state transitions

Created Alive

Terminated

new Thread()

start()

stop(), orrun() returnsstop()

The predicate isAlive() is used to test if a thread has been started but not terminated. Once terminated, a thread cannot be restarted.

start() causes the thread to call its run() method.

Page 3: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Java Thread Life CycleJava Thread Life Cycle

An “alive” thread has a number of sub-states

Runnable Non-Runnablesuspend()

resume()

yield()

Running

dispatch

suspend()

start()

stop(), orrun() returnswait() makes a Thread non-runnable,

and notify() makes it runnable (both of these methods are discussed later)

sleep()

Page 4: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Java Thread Life Cycle in FSPJava Thread Life Cycle in FSP

THREAD = CREATED,CREATED = (start ->RUNNING |stop ->TERMINATED),RUNNING = ({suspend,sleep}->NON_RUNNABLE |yield ->RUNNABLE |{stop,end} ->TERMINATED |run ->RUNNING),RUNNABLE = (suspend ->NON_RUNNABLE |dispatch ->RUNNING |stop ->TERMINATED),NON_RUNNABLE = (resume ->RUNNABLE |stop ->TERMINATED),TERMINATED = STOP.

Page 5: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Java Thread Life Cycle in LTSJava Thread Life Cycle in LTS

end, run, dispatch are not methods of class Thread.

States 0 to 4 correspond to CREATED, TERMINATED, RUNNING, RUNNABLE, and NON_RUNNABLE respectively.

Page 6: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Thread Methods to AvoidThread Methods to Avoid

● Some Thread methods should be avoided destroy(), resume(), stop(), suspend()

▴ These methods have been deprecated An original design mistake that is maintained purely for backwards

compatibility purposes

▴ They are inherently unsafe Leaves state in an unknown condition

Page 7: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Hello World Java Thread ExampleHello World Java Thread Example

HELLO=(hello->STOP).WORLD=(world->STOP).||HELLO_WORLD=(HELLO || WORLD).

How do we implement this in Java?

Page 8: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Hello World Java Thread ExampleHello World Java Thread Example

public class Hello implements Runnable { private String s; public Hello(String s) { this.s = s; } public void run() { System.out.println(s); } public static void main(String[] argv) { Thread t1 = new Thread(new Hello("Hello")); Thread t2 = new Thread(new Hello("World")); t1.start(); t2.start(); }}

Page 9: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Countdown Timer Example in JavaCountdown Timer Example in Java

COUNTDOWN (N=3) = (start->COUNTDOWN[N]),COUNTDOWN[i:0..N] =

(when(i>0) tick->COUNTDOWN[i-1] |when(i==0) beep->STOP

|stop->STOP).

How do we implement this in Java?

Page 10: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Countdown Timer Example in JavaCountdown Timer Example in Java

public class CountDown implements Runnable { private final static int N = 10; private Thread thread;

public void start() { ... } public void stop() { ... } public void run() { ... } private void tick(int i) { ... }}

High-level implementation approach

Page 11: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Countdown Timer Example in JavaCountdown Timer Example in Java

public void start() { thread = new Thread(this); thread.start();}public void stop() { thread = null;}public void run() { int i = N; while (i >= 0) { if (thread == null) return; else if (i == 0) System.out.println("beep"); else if (i > 0) tick(i); i--; }}private void tick(int i) { System.out.println("tick: " + i); try { Thread.sleep(1000); } catch (InterruptedException ex) { }}

start action

stop action

COUNTDOWN[i] process recursion as a while loop STOP

when(i==0) beep->STOP

when(i>0) tick->CD[i-1]

STOP occurs whenrun() returns

tick action

Page 12: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Countdown Timer Example in JavaCountdown Timer Example in Javapublic class Main extends JFrame { private static final String START = "Start"; private static final String STOP = "Stop"; private CountDown counter; private JButton startButton; private JButton stopButton; public Main(CountDown counter) { super("CountDown Example"); this.counter = counter; setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().add(startButton = new JButton(START), BorderLayout.WEST); getContentPane().add(stopButton = new JButton(STOP), BorderLayout.EAST); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent event) { if (((JButton) event.getSource()).getText().equals(START)) { Main.this.counter.start(); } else { Main.this.counter.stop(); } } }; startButton.addActionListener(al); stopButton.addActionListener(al); pack(); } public static void main(String[] args) { CountDown counter = new CountDown(); Main main = new Main(counter); main.setVisible(true); }}

Page 13: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Multiple Threads in JavaMultiple Threads in Java

● In the previous examples, we only created one thread, Java programs can create many threads

● Actually, every Java program has multiple threads

A program starts with its own thread that calls main()

Various background threads exist, like the garbage collector

● Creating multiple threads is as simple as creating multiple Thread instances using new

Page 14: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Recall the Ornamental GardenRecall the Ornamental Garden

const N = 4range T = 0..Nset VarAlpha = { value.{read[T],write[T]} }

VAR = VAR[0],VAR[u:T] = (read[u]->VAR[u] |write[v:T]->VAR[v]).

TURNSTILE = (go->RUN),RUN = (arrive->INCREMENT |end->TURNSTILE),INCREMENT = (value.read[x:T] ->value.write[x+1]->RUN )+VarAlpha.

||GARDEN = (east:TURNSTILE ||west:TURNSTILE ||{east,west,display}::value:VAR) /{go/{east,west}.go, end/{east,west}.end}.

Page 15: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Ornamental Garden in JavaOrnamental Garden in Java

The threaded Turnstile simulates the periodic arrival of a visi-tor to the garden by sleeping for half a second and then invoking the increment() method of the counter object.

Page 16: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Ornamental Garden in JavaOrnamental Garden in Java

public static void main(String[] args) { Counter value = new Counter(); Turnstile west = new Turnstile("West", value); Turnstile east = new Turnstile("East", value); new Thread(west, west.getName()).start(); new Thread(east, east.getName()).start();}

The Counter object and Turnstile threads are created by the main() method of the Garden object:

||GARDEN = (east:TURNSTILE ||west:TURNSTILE ||{east,west,display}::value:VAR) /{go/{east,west}.go, end/{east,west}.end}.

From original FSP:

Page 17: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Ornamental Garden in JavaOrnamental Garden in Java

public class Turnstile implements Runnable { private final String name; private final Counter value; public Turnstile(String name, Counter value) { this.name = name; this.value = value; } public String getName() { return name; } public void run() { try { int total = 0; for (int i = 1; i <= Garden.MAX; i++) { Thread.sleep(500); total++; value.increment(); } System.out.println("Total arrivals at '" + name + "' = " + total); } catch (InterruptedException ex) { } }}

The run() method exits and the thread terminates after Garden.MAX visitors have entered.

Page 18: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Ornamental Garden in JavaOrnamental Garden in Java

public class Counter { private int v = 0;

public void increment() { int temp = v; // Read the current value. Simulate.interrupt(); v = temp + 1; // Write updated value. System.out.println("value = " + v + " (" + Thread.currentThread().getName() + ")"); }}

Hardware interrupts can occur at arbitrary times.

The Counter class simulates a hardware interrupt during an increment(), between reading and writing to the shared counter value. The Simulate.interrupt() method randomly calls Thread.yield() to force a thread switch.

Page 19: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Ornamental Garden in JavaOrnamental Garden in Java

Remember that we found a bug in our FSP implementation of the Ornamental Garden; the same bug exists in our Java implementation:

This bug results from the threads interfering with each other...how do we solve this problem in Java?

Total arrivals at 'West' = 20Total arrivals at 'East' = 20value = 32 (East)

Page 20: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Avoiding Interference in ProgramsAvoiding Interference in Programs

// Public static space

Value v = new Value(0);

boolean lock = false;

// Thread 1

while (lock) { } // wait

lock = true; // lock

x = v.read();

v.write(x + 1);

System.out.println(v.read());

lock = false;

// Thread 2

while (lock) { } // wait

lock = true; // lock

x = v.read();

v.write(x + 1);

System.out.println(v.read());

lock = false;

Naïve SolutionThis will not work, even if setting “lock” is atomic, due to arbitrary instruction interleaving -- a thread may jump ahead of current one

Page 21: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Avoiding Interference in ProgramsAvoiding Interference in Programs

● What is the programmatic solution? It is not generally possible using conventional

programming language constructs Must have special support for synchronization

▴ Either language support or library support▴ Actually, solution is provided through hardware support

Atomic “test-and-set” instruction (or similar)

▴ This “special” support provides a means to guarantee that some minimal instruction can be done atomically

▴ From this minimal atomic instruction, it is possible to build higher level synchronization concepts

Page 22: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Mutual Exclusion in JavaMutual Exclusion in Java

Java associates a lock with each object. Concurrent activations of a method in Java can be made mutually exclusive by prefixing the method with the keyword synchronized.

We correct Counter class by deriving a class from it and making the increment method synchronized

class SynchronizedCounter extends Counter {

public synchronized void increment() { super.increment(); }}

Page 23: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Mutual Exclusion in JavaMutual Exclusion in Java

The Java compiler inserts code to acquire the lock before executing the body of the synchronized method and code to release the lock before the method returns. Concurrent threads are blocked until the lock is released.

Total arrivals at 'West' = 20Total arrivals at 'East' = 20value = 40 (East)

Page 24: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Synchronized Methods are RecursiveSynchronized Methods are Recursive

public synchronized void increment(int n) { if (n > 0) { value++; increment(n - 1); }}

Once a thread has access to a synchronized method, it can enter the method again and again (since it already has the lock), for example:

Conceptually, each entry into the synchronized method increments a lock counter and each exit decrements the lock counter. When the conceptual lock counter reach-es zero then the lock is once again free.

Page 25: Lecture 8: Java Thread Introduction - Tufts CS · Java Thread Life Cycle An overview of the life cycle of a thread as state transitions Created Alive Terminated new Thread() start()

Java Synchronized StatementJava Synchronized Statement

synchronized (object) { statements }

synchronized (counter) { counter.increment(); }

Access to an object may also be made mutually exclusive by us-ing the synchronized statement:

A less elegant way to correct the garden example would be to modify the Turnstile.run() method:

Why is this less elegant?