Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no...

29
Java threads Carlo U. Nicola, IMVS With extracts from slides/publications of : Brian Goetz and Dominik Gruntz, IMVS

Transcript of Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no...

Page 1: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Java threads

Carlo U. Nicola, IMVS

With extracts from slides/publications of :

Brian Goetz and

Dominik Gruntz, IMVS

Page 2: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Topics

1. Thread Definition

2. Thread Synchronization

3. Condition Variables

4. Volatile

MAS HS12 2

Page 3: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

What are threads?

MAS HS12 3

A process is an executing program that: – is memory allocated by OS

– usually does not share memory with other processes

A thread is a single sequential flow of control that: – runs in the address space of a process

– has its own program counter

– has its own stack frame

– shares code and data with other threads.

UML diagram:

Page 4: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

java.lang.Thread

java.lang.Thread = Infrastructure (PC, Stack)

java.lang.Runnable = Code

MAS HS12 4

public class R implements Runnable {

private int nr;

public R(int nr){this.nr = nr;}

public void run() {

for(int i=0; i<10; i++) {

System.out.println(”Hello” + nr + ” ” + i);

}

}

}

...

java.lang.Thread Runnable r = new R(1);

Thread t = new Thread(r);

Runnable

run()

Thread R

run()

- run() has no parameters

- run() returns no result

- run() does not declare

any checked exception

Page 5: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Starting the thread

MAS HS12 5

Constructor initializes the thread object: Thread t = new Thread(r); t.start();

– calls the thread object’s run method (! turn power on)

– when run( ) returns, the thread terminates

public class Test { static void main(String[] args){ Thread t1 = new Thread(new R(1)); Thread t2 = new Thread(new R(2)); t1.start(); t2.start(); } }

Hello1 0

Hello2 0

Hello1 1

Hello2 1

Hello2 2

Hello2 3

Hello2 4

Hello2 5

Hello2 6

Hello2 7

Hello2 8

Hello2 9

Hello1 2

Hello1 3

Hello1 4

Hello1 5

Hello1 6

Hello1 7

Hello1 8

Hello1 9

Process

Exit..

Page 6: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Scheduling

Scheduling: – Per processor, only one thread is running at any given time – Scheduling = Allocation of CPU time to threads

Threading models: – Cooperative threading ! pseudo parallelism

# threads decide, when they should give up the processor to other threads. Example: yield(); sleep(1000);

– Pre-emptive threading ! quasi parallelism # OS interrupts threads at any time (time sliced) # no thread can unfairly hog the processor

JVM does not mandate a threading model – Java programmers must write programs for both models!

MAS HS12 6

Page 7: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Alternative definition of a Java thread

MAS HS12 7

Since the class Thread implements the interface Runnable, the method

run() can be implemented in subclass of Thread. Example:

public class T extends Thread { private int nr; public T(int nr) {this.nr = nr;} public void run() { for (int i=0; i<10; i++) { System.out.println(”Hello” +nr + ” ” + i); } } }

Runnable

run()

T

Thread

run()

run()

Page 8: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Extending Thread vs implementing Runnable

Implement Runnable in a separate class: – the existing class should provide code for the thread ! no multiple

subclassing problem

– you must implement run()

Implementing Runnable in extension of Thread – easy access to thread methods

# static methods: sleep(100); Thread.sleep(100);

# instance methods: getName(); Thread.currentThread().getName();

MAS HS12 8

Page 9: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Thread class

static Thread currentThread(): – returns a reference to the currently executing thread object.

static void sleep(long millis): – Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds.

static void yield(): – Causes the currently executing thread object to temporarily pause and

allow other threads to execute.

void run() void start() void join():

– Waits for this thread to die.

void join(long millis): – Waits at most millis milliseconds for this thread to die.

MAS HS12 9

Page 10: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Thread class join()

MAS HS12 10

public class Test1 { static void main(String[] args) { Thread t1 = new Thread(new R(1)); Thread t2 = new Thread(new R(2)); t1.start(); t2.start(); System.out.println("done"); } }

What is the program’s output?

Page 11: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Thread class join()

MAS HS12 11

public class Test1 { static void main(String[] args){ Thread t1 = new Thread(new R(1)); Thread t2 = new Thread(new R(2)); t1.start(); t2.start(); try { t1.join(); // waits until t1 has terminated t2.join(); // waits until t2 has terminated } catch(InterruptedException e){ } System.out.println("done"); } }

What is the program’s output?

Page 12: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Further methods of the Thread class

MAS HS12 12

String getName(): – Returns this thread's name.

void setName(String name) – Changes the name of this thread to be equal to the argument

name. int getPriority()

– Returns this thread's priority. void setPriority(int newPriority)

– Changes the priority of this thread. boolean isDaemon() – Tests if this thread is a daemon thread. void setDaemon(boolean on) – Marks this thread as either a daemon thread or a user thread.

boolean isAlive()

– Tests if this thread is alive.

Page 13: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Thread class: Deamons

MAS HS12 13

Daemon Threads

– daemon threads run in the background

– if only deamon threads are active, the process stops.

public class Test1 { static void main(String[] args){ Thread t1 = new Thread(new R(1)); Thread t2 = new Thread(new R(2)); t2.setDaemon(true); t1.start(); t2.start(); } }

What is the program’s output?

Page 14: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Thread states

MAS HS12 14

Page 15: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Example: unresponsive UI

MAS HS12 15

Button start = new Button("Start"); start.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e){ go();} } ); public void go() { while(true){ // thread sleeps for 100ms try {Thread.sleep(100);} catch (InterruptedException e){} t.setText("" + count++); } }

Page 16: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Solution: unresponsive UI

MAS HS12 16

Button start = new Button("Start"); start.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e){ new Thread(UI.this).start();} } ); public void run(){ while(true){ // thread sleeps for 100ms try {Thread.sleep(100);} catch (InterruptedException e){} t.setText("" + count++); } }

Page 17: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Quiz

MAS HS12 17

class C { int x = 0, y = 0; void a() { x = 3; y = 4; } int b() { int z = y; z = z + x; return z; } }

One thread calls method a() on an instance of C One thread calls method b() on the same instance.

Question: what results can be returned by b() ?

Page 18: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Demo: Adder

MAS HS12 18

class TTest { static double x = 0.0; public static void add(double val){x = x + val;} public static void main(String[] args){ class TestThread extends Thread { private double val; TestThread(double val){this.val = val;} public void run(){ for(int i=0; i<1000; i++){ add(+val); add(-val); } } }

Page 19: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Demo: Adder cont.

MAS HS12 19

TestThread t1 = new TestThread(120); TestThread t2 = new TestThread(60); TestThread t3 = new TestThread(20); TestThread t4 = new TestThread(55.5); t1.start(); t3.start(); t2.start(); t4.start(); try { t1.join(); t2.join(); t3.join(); t4.join(); } catch(InterruptedException e){ } System.out.println(x); } }

Page 20: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

MAS HS12 20

An important definition (Brian Goetz):

A class is thread safe if it behaves always in the same manner (i.e. correctly)

when accessed from multiple threads, regardless of the scheduling or

interleaving of the execution of these threads by the runtime environment

and with no additional synchronization on the part of the calling code.

Remember: Stateless objects (immutable classes) do not have fields and

they do not reference fields from other classes therefore they

are always thread safe.

Threads and shared resources

Page 21: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

MAS HS12 21

class Counter { private final int count; public Counter() { count = 0; } public void increment() { count++; } public void decrement() { count--; } public int getValue() { return count; } } class IncThread extends Thread { private final Counter c; public IncThread(Counter p_c) { c = p_c; } public void run() { while (true) { c.increment(); System.err.println ("Running inc thread: " + currentThread() + " / Value: " + c.getValue()); } } }

Example: Yarn with increment …

Page 22: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

MAS HS12 22

class DecThread extends Thread { private final Counter c; public DecThread(Counter p_c) { c = p_c; } public void run() { while (true) { c.decrement(); System.err.println("Running dec thread: " + currentThread() + " / Value: " + c.getValue()); } } } public class Yarn { public static void main(String args[]) { Counter c = new Counter(); IncThread ithread = new IncThread(c); DecThread dthread = new DecThread(c); ithread.start(); dthread.start(); }}

Example: Yarn with decrement …

Page 23: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

MAS HS12 23

Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running inc thread: Thread[Thread-0,5,main] / Value: 2 Running inc thread: Thread[Thread-0,5,main] / Value: 3 Running inc thread: Thread[Thread-0,5,main] / Value: 4 … Running inc thread: Thread[Thread-0,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running inc thread: Thread[Thread-0,5,main] / Value: 62 Running dec thread: Thread[Thread-1,5,main] / Value: 61 Running dec thread: Thread[Thread-1,5,main] / Value: 60 … Running dec thread: Thread[Thread-1,5,main] / Value: 1 Running dec thread: Thread[Thread-1,5,main] / Value: 0 Running dec thread: Thread[Thread-1,5,main] / Value: -1 Running inc thread: Thread[Thread-0,5,main] / Value: -1 Running inc thread: Thread[Thread-0,5,main] / Value: 0 Running inc thread: Thread[Thread-0,5,main] / Value: 1 Running inc thread: Thread[Thread-0,5,main] / Value: 2 …

Why such a mess? A shared resource

(in our case the Counter c) is accessed

without any order by several threads!

Our small program is not thread safe.

What can we do?

(1) Do not share state variables across threads.

(2) Make state variable immutable.

(3) Use synchronization whenever you access state variables.

Output of Yarn

Page 24: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Any race conditions? Yes!

MAS HS12 24

class IncThread extends Thread { private final Counter c; public IncThread (Counter p_c) { c = p_c; } public void run() { while (true) { c.increment(); System.err.println ("Running inc thread: " + currentThread() + " / Value: " + c.getValue()); } } }

We have always thread unsafe applications when we use compound

operations like:

(1) Read-Modify-Write (RMW)

(2) Check-Then-Act (CTA)

that are not atomic! Atomic means that RMW and CTA are executed from

start to finish by only one thread at a time.

Page 25: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

MAS HS12 25

public void run () { while (true) { synchronized (c) { c.increment (); System.err.println ("Running inc thread: " + currentThread () + " / Value: " + c.getValue ()); } } }

Synchronized blocks:

– Every object contains a single lock

– A lock is taken when synchronized section is entered

– If the lock is not available, thread enters a waiting queue

– If the lock is returned any (longest waiting?) thread is resumed

How to synchronize?

Page 26: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

synchronized

MAS HS12 26

On instance methods:

– often a method is synchronized on “this”:

public void push(int x){synchronized(this){……}} – short form:

public synchronized void push(int x){……} On class methods (static)

– A lock is also associated with each class, this lock is different from

the locks of the instances:

public static synchronized void foo(){……} similar to: class C { public static void foo(){synchronized(C.class){…}} }

Page 27: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Monitors

MAS HS12 27

Data protection:

– A synchronized lock does not protect data but it only synchronizes

threads

– Data can still be manipulated by direct access # declare data as private

– Data can still be accessed by unsynchronized threads # synchronize all methods which can access critical data

sleep:

– sleep() does not release ownership of any lock

Java does not provide monitors, but monitors can be implemented

with Java

Page 28: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Example: Copy machine

MAS HS12 28

class CopyMachine { public synchronized void makeCopies( Document d, int nCopies){ // only one thread at a time Original org = scanOriginal(d); for(int i=0; i<n; i++) { Paper p = getPaper(); copy(org, p); } } public void loadPaper (Paper[] p) { // multiple threads can access this putPaper(p) } }

Problem: How can we intelligently synchronize the access to the paper drawer?

Page 29: Java threads - web.fhnw.ch · – the existing class should provide code for the thread ! no multiple subclassing problem – you must implement run() Implementing Runnable in extension

Fine-grained access

MAS HS12 29

class CopyMachine { private Object paperLock = new Object(); public synchronized void makeCopies( Document d, int nCopies){ // only one thread at a time Original org = scanOriginal(d); for(int i=0; i<n; i++) { Paper p = getPaper(); copy(org, p); } } public void loadPaper (Paper[] p) { synchronized(paperLock){ putPaper(p) } } }

One lock at the object level (this) may be too coarse:

– use dummy objects as simple locks