multithreading horstmann ch.9. multithreading threads thread states thread interruption race...

47
Multithreading Horstmann ch.9

Upload: helen-warren

Post on 16-Dec-2015

246 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

Horstmann ch.9

Page 2: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states

• Thread interruption

• Race condition

• Lock

• Built-in lock

• java.util.concurrent library

• Animation example

Page 3: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Single vs. Multiple Threads

• Finish each line of bullets before starting new line

• Allow simultaneous drawing of several lines

ThreadTester1

ThreadTester2

Page 4: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Single vs. Multiple Threads

Using single thread:

in method actionPerformed:

...

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

”draw single bullet”;

Thread.sleep(500);

}

...

Page 5: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Running Threads

public class MyRunnable implements Runnable {public void run() { thread action}

}

...

Runnable r = new MyRunnable();

Thread t = new Thread(r);

t.start();

Specify action

Construct thread from Runnable object

Start thread

Page 6: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Single vs. Multiple Threads

Using single thread:

in method actionPerformed:

...

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

”draw single bullet”;

Thread.sleep(500);

}

...

Using multiple threads:

In method actionPerformed:

Runnable r = new Runnable() { public void run() {

}

}

Thread t = new Thread(r);

t.start();

Page 7: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZ

public static void main(String[] args) {

Runnable r1 = new Producer();

Runnable r2 = new Producer();

Thread t1 = new Thread(r1);

Thread t2 = new Thread(r2);

t1.start();

t2.start();

}

How many threads?

1.None

2.One

3.Two

4.Three

5. I don’t know

Page 8: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Starting Two Threadspublic static void main(String[] args) {

Runnable r1 = new Producer();

Runnable r2 = new Producer();

Thread t1 = new Thread(r1);

Thread t2 = new Thread(r2);

t1.start();

t2.start();

}

Page 9: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads

• Thread states• Thread interruption• Race condition• Lock• Built-in lock• java.util.concurrent library• Animation example

Page 10: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Thread states• Each thread has

– State (new, runnable, blocked, dead), and– priority

Thread blocked when•Sleeping•Waiting for I/O•Waiting to acquire lock•Waiting for condition

Scheduler activates the runnable thread of max priority if• a thread has completed its time slice• a thread has blocked itself• a thread with higher priority has become runnable

Page 11: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Thread schedulingpublic static void main(String[] args) {

Runnable r1 = new Producer(“goddag”);

Runnable r2 = new Producer(“farvel”);

Thread t1 = new Thread(r1);

Thread t2 = new Thread(r2);

t1.start();

t2.start();

}

Output depends on scheduler:

“goddag”

“goddag”

“farvel”

“farvel”

“farvel”

“goddag”

“farvel”

public class Producer implements Runnable { public Producer(String a) { greeting = a; } public void run() { try { for (int i = 1; i <= 10; i++) { System.out.println(i + ": " + greeting); Thread.sleep(100); } } catch (InterruptedException e) {} } private String greeting;}

Page 12: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZ

Thread T1 based on run method

public void run {

try { Thread.sleep(100000); }

catch (InterruptedException e) {}

}

Thread T2 based on run method

public void run {

factor(785678564567385635789)

}

Which thread(s)

become blocked?

1.None

2.T1

3.T2

4.Both

5. I don’t know

factor method from ”noter” ch. 1

Page 13: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states

• Thread interruption• Race condition• Lock• Built-in lock• java.util.concurrent library• Animation example

Page 14: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Thread interaction

• Recursive Fibonacci– May take long time – Window freezes

• Compute in separate threads– Old slow thread may overwrite result from

new fast thread?– Interrupt old threads!

ThreadTester3

Page 15: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Terminating Threads

• Thread terminates when run exits

• Or ask thread to finish by calling interrupt

• Thread may check for interrupt by callThread.currentThread().isInterrupted()

• sleep, wait throw InterruptedException when thread interrupted

Page 16: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

private Thread t = null;

public void actionPerformed(ActionEvent e) {

if (t!=null) t.interrupt();

Runnable r = new Runnable() {

public void run() {

try {

long res = fib(Integer.parseInt(input.getText()));

if (!Thread.currentThread().isInterrupted())

recResult.setText(res+"");

} catch (InterruptedException e) {}

}

};

t = new Thread(r);

t.start();

}

private long fib(int n) throws InterruptedException {

if (Thread.currentThread().isInterrupted())

throw new InterruptedException();

if (n <= 1) return 1; else return fib(n - 1) + fib(n - 2);

}

Code of anonymous class implementing ActionListener

Page 17: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZ

public class Test1 implements Runnable {

public void run() {

try {

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

System.out.println(i);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

} } }

The catch statement is empty?1. Compiler error

2. Legal code, but better style to omit try-catch

3. Legal code, try-catch is necessary, but empty catch is bad style

4. Legal code, try-catch is necessary, empty catch is good style

5. I don’t know

Page 18: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states• Thread interruption

• Race condition• Lock• Built-in lock• java.util.concurrent library• Animation example

Page 19: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Shared Resource

Producer Thread

”goddag”

Producer Thread ”farvel”

Consumer Thread

Queue object

Bounded Queue:max 10 elements

Page 20: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Producer Thread

int i = 1;

while (i <= 100) {

if (!queue.isFull()) {

queue.add(i + ": " + greeting);

i++;

}

Thread.sleep((int)(Math.random() * DELAY));

}

Page 21: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Consumer Thread

int i = 1;while (i <= 100) { if (!queue.isEmpty()) { Object greeting = queue.remove(); System.out.println(greeting); i++; } Thread.sleep((int)(Math.random() * DELAY)); }

Page 22: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

• Expected Program Output

1: goddag1: farvel2: goddag 3: goddag ... 99: farvel 100: farvel

• Possible output

...

10: goddag

11: farvel

...

15: goddag

11: farvel

...

• Why?

Page 23: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Queue:Circular Array Implementation

public void add(E newValue) { elements[tail] = newValue; tail++; size++; if (tail == elements.length) { tail = 0; } }

Page 24: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Race Condition• First thread calls add and executes

elements[tail] = newValue;  First thread at end of time slice

• Second thread calls add and executeselements[tail] = newValue;

tail++;  Second thread at end of time slice

• First thread executestail++; 

Page 25: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZProducer Thread:BoundedQueue<String> queue =

new BoundedQueue<String>(10);

for (int i = 1; i <= 100; i++) {

queue.add(i + ": " + greeting);

Thread.sleep((int)(Math.random() * DELAY));

}

Consumer Thread:BoundedQueue<String> queue = new BoundedQueue<String>(10);for (int i = 1; i <= 100; i++) { Object greeting = queue.remove(); System.out.println(greeting); Thread.sleep((int)(Math.random() * DELAY)); }

Could race condition occur when running these thread in parallel?1.Yes2.No3.I don’t know

Page 26: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states• Thread interruption• Race condition

• Lock• Built-in lock• java.util.concurrent library• Animation example

Page 27: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Locks

• Thread can acquire lock • When another thread tries to acquire same lock,

it blocks • When first thread releases lock, other thread is

unblocked and tries again • Two kinds of locks

– Objects of class implementing java.util.concurrent.Lock interface type, usually ReentrantLock

– Locks that are built into every Java object

Page 28: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

private Lock aLock = new ReentrantLock();. . .

public void add(E newValue) { aLock.lock(); try { elements[tail] = newValue; tail++; size++; if (tail==elements.length) tail = 0; } finally { aLock.unlock(); }}

Consumer or producer thread executing lock() has exclusive access to add/remove methods – even when

time slice is up – until unlock()

public E remove() { aLock.lock(); try { E r = (E) elements[head]; head++; size--; if (head==elements.length) head = 0; return r; } finally { aLock.unlock(); }}

Page 29: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Producer Thread

int i = 1;

while (i <= 100) {

if (!queue.isFull()) {

queue.add(i + ": " + greeting);

i++;

}

Thread.sleep((int)(Math.random() * DELAY));

}

Good: add is protected by

lock

Bad: Another producer thread may fill up the queue between isFull() check

and add()

Solution: Must move isFull() check inside protected add()

Page 30: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZ

public void add(E newValue) throws InterruptedException { aLock.lock(); try { while( isFull() ) { Thread.sleep(1000); } ... } finally {aLock.unlock();}}

Does it work?

1: No, race condition may still occur

2: Yes, race condition cannot occur, and this code works fine

3: ??? – race condition cannot occur – but a new problem arises…

4: I don’t know

isfull() check is now inside lock protected add()

Page 31: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZ

public void add(E newValue) throws InterruptedException { aLock.lock(); try { while( isFull() ) { Thread.sleep(1000); } ... } finally {aLock.unlock();}}

Does it work?

1: No, race condition may still occur

2: Yes, race condition cannot occur, and this code works fine

3: ??? – race condition cannot occur – but a new problem arises…

4: I don’t know

isfull() check is now inside lock protected add()

”Deadlock”: Since the queue remains locked, no consumer thread can execute remove() and make isFull() false

Page 32: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Using condition object to avoid deadlock

private Lock aLock = new ReentrantLock();private Condition spaceAvailableCondition = aLock.newCondition();

public void add(E newValue) throws InterruptedException { aLock.lock(); try {

while (isFull()) spaceAvailableCondition.await(); . . . } finally {aLock.unlock();}}

public E remove() throws InterruptedException { aLock.lock(); try { . . . spaceAvailableCondition.signalAll(); return r; } finally {aLock.unlock();}}

Calling await blocks the thread and releases the

lock

Calling signalAll() unblocks all threads

awaiting this condition

(they remain blocked until getting the lock)

Page 33: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states• Thread interruption• Race condition• Lock

• Built-in lock• java.util.concurrent library• Animation example

Page 34: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Object Locks• Each object has a lock • Calling a synchronized method acquires lock of implicit parameter • Leaving the synchronized method releases lock • Easier than explicit Lock objects

public class BoundedQueue<E> {

public synchronized void add(E newValue) { ... }

public synchronized E remove() { ... }

...}

Page 35: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Object Locks

• Each implicit lock has one associated (anonymous) condition object

• wait() blocks current thread and adds it to wait set

• notifyAll() unblocks waiting threads

public synchronized void add(E newValue) throws InterruptedException {

while (isFull()) wait();elements[tail] = anObject;. . .notifyAll();

}

Just one condition objectUsed by both threads waiting due to full queue and due to

empty queue

Page 36: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZWhat is not reason for blocking a thread?

1. Sleeping

2. Waiting for I/O

3. Time slice is up

4. Waiting to acquire lock

5. Waiting for a condition

6. I don’t know

Page 37: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

QUIZWhen is InterruptedException thrown?

1. when Thread.sleep(..) returns

2. when <condition>.await() returns

3. when other thread calls this threads interrupt method while this thread is blocked

4. I don’t know

Page 38: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states• Thread interruption• Race condition• Lock• Built-in lock

• java.util.concurrent library• Animation example

Page 39: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Use java.util.concurrent libraryMain thread:BlockingQueue<String> queue =

new LinkedBlockingQueue<String>(10);

Producer Thread:for (int i = 1; i <= 100; i++) {

queue.put(i + ": " + greeting);

Thread.sleep((int)(Math.random() * DELAY));

}

Consumer Thread:for (int i = 1; i <= 100; i++) { Object greeting = queue.take(); System.out.println(greeting); Thread.sleep((int)(Math.random() * DELAY)); }

Synchronized queue with space for 10 elements

Producer thread is made to wait until queue has available

space

Consumer thread is made to wait until queue is nonempty

Page 40: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Multithreading

• Threads• Thread states• Thread interruption• Race condition• Lock• Built-in lock• java.util.concurrent library

• Animation example

Page 41: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Algorithm Animation• Use thread to make progress in algorithm • Display algorithm state • Example: Animate MergeSorter (similar to java.util.Arrays.sort)• Pause inside compare method • Pass custom comparator

Comparator<Double> comp = new   Comparator<Double>() {      public int compare(Double d1, Double d2) {         draw current state         pause thread         return d1.compareTo(d2);      }   };

Page 42: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Algorithm Animation

Page 43: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

public class Sorter implements Runnable { public Sorter(Double[] values, ArrayComponent panel) { this.values = values; this.panel = panel; } public void run() { Comparator<Double> comp = new Comparator<Double>() { public int compare(Double d1, Double d2) { panel.setValues(values, d1, d2); try { Thread.sleep(DELAY); } catch (InterruptedException exception) { Thread.currentThread().interrupt(); } return d1.compareTo(d2); }; MergeSorter.sort(values, comp); panel.setValues(values, null, null); } private Double[] values; private ArrayComponent panel; private static final int DELAY = 100; }

array being sorted

Page 44: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Pausing and Running the Animation

• Want to pause animation until "Run" or "Step" button is clicked

• Need to coordinate UI thread, animation thread • Try to use built-in thread-safe construct in

java.util.concurrent • Trick: Use a blocking queue • Button click adds string "Run" or "Step" to queue • Animation thread calls take on the queue, blocks

if no string insertedBlockingQueue<String> queue;

Page 45: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

User Interface ThreadstepButton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent event) { queue.add("Step"); runButton.setEnabled(true); } });

runButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { runButton.setEnabled(false); queue.add("Run"); } });

Page 46: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library

Animation Threadpublic int compare(Double d1, Double d2) { try { String command = queue.take();

if (command.equals("Run")) { Thread.sleep(DELAY); if (!"Step".equals(queue.peek())) queue.add("Run"); } } catch (InterruptedException exception) { Thread.currentThread().interrupt(); } panel.setValues(values, d1, d2); return d1.compareTo(d2); }

... private BlockingQueue<String> queue;

Page 47: Multithreading Horstmann ch.9. Multithreading Threads Thread states Thread interruption Race condition Lock Built-in lock java.util.concurrent library