26
Practice Session 8 Blocking queues Producers-Consumers pattern • Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread cancellation: Stop shouldStop Interrupt

Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Embed Size (px)

Citation preview

Page 1: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Practice Session 8

• Blocking queues• Producers-Consumers pattern• Semaphore• Futures and Callables• Advanced Thread Synchronization

Methods• CountDownLatch

• Thread cancellation:• Stop• shouldStop• Interrupt

Page 2: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Blocking Queues

• An ordinary queue with a special feature.• The queue behaves differently in two cases:– Empty queue case• Thread wants to pop head element of the queue.• Thread is blocked until the queue stops being empty

– Full queue case• Thread wants to add an element to the queue.• Thread is blocked until the queue stops being full

Page 3: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Java Blocking Queue• API:

– Package java.util.concurrent– Interface: BlockingQueue<E>

• “Our” Implementation:– class MyBlockingQueue<E> implements BlockingQueue<E>

• Java’s Implementation:– Java.util.concurrent.ArrayBlockingQueue<E>

• Functions:– void put(E o)

• Adds the specified element to this queue, waiting if necessary for space to become available.

– E take()• Retrieves and removes the head of this queue, waiting if no elements are present on this queue.

• API Website:– http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html– http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ArrayBlockingQueue.html

Page 4: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

MyBlockingQueue• Private Fields:

private ArrayList<E> fList; • The queue object.• Not synchronized.

private final int fMax; • Our queue’s maximum size. • Received upon construction. • Fixed Size.

• Constructor:MyBlockingQueue(int max){

fList = new ArrayList();fMax = max;

}• Private Functions:

private synchronized int getSize(){ return fList.size();

}

Page 5: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

My Blocking Queue – put()

public synchronized void put(E obj){ while(getSize()>=fMax){ try{ this.wait(); } catch (InterruptedException ignored){} } fList.add(obj); // wakeup everybody. If someone is waiting in the get() // method, it can now perform the get. this.notifyAll(); }

Page 6: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

MyBlockingQueue – take()

public synchronized E take(){

while(size()==0){ try{ this.wait(); } catch (InterruptedException ignored){} } E obj = fList.get(0); fList.remove(0); // wakeup everybody. If someone is waiting in the add() // method, it can now perform the add. this.notifyAll(); return obj; }

Page 7: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

The Producer-Consumer Problem• A classical multi-process (thread) synchronization problem. • Uses a bounded (fixed-size) queue.• Two major groups:

– Producer(s):• A Thread that generates new objects• Adds them to shared space

– Consumer(s):• A Thread that removes objects from shared space.• Uses them.

• Full queue:– A producer thread is blocked, until a free space is available.

• Empty queue:– A consumer thread is blocked, until the queue receives new object.

Page 8: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Producer-Consumer Implementation• Using ArrayBlockingQueue • Three Classes:

– Producer implements Runnable– Consumer implements Runnable– Driver class (includes main function)

• Code Example:– Producer-Consumer

• The output of the program does not necessarily reflect its flow, since printing and accessing the queue are 2 separate operations (the operating system might decide to run the first command, and then stops the thread and runs another thread, before this thread performs the second command).

• Surrounding the 2 commands with a synchronized block solves this problem, but it’s not advisable since it blocks too much.

Page 9: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

java.util.concurrent.Semaphore

• A data structure used to restrict access to shared resources.• A synchronized block allows access for one thread at a time.• A semaphore gives N>=1 permits to threads, at the same time, over a

resource/the code that comes after semaphore.acquire(<number>). • If the program uses acquire(), without a number, then the semaphore

gives access to N threads.

API:– http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/

Semaphore.html

Page 10: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

• Semaphore construction:– Semaphore sem = new Semaphore(int permits):

• permits holds the maximal number of possible threads to access an object at the same time.

• Fairness is false in this case, permits are given in an arbitrary order.

– Semaphore sem = new Semaphore(int permits, boolean fair) • Fairness is true, gives permits to threads in FIFO manner.• First thread requesting access, is given access.• Downside:

– It takes more time for the virtual machine to order the acquisition of the permits than to allow an arbitrary thread to acquire a permit.

Page 11: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

• sem.release(): releases a permit returning it to the semaphore.• sem.release(n): releases n permits - adds n permits to the

semaphore (n can be larger than the value we used at initialization).

• sem.reducePermits(n): shrinks the number of available permits by the indicated reduction; does not block like acquire(). (protected method)

• sem.acquire(): acquire a permit• sem.acquire(n ): acquire n permits• More methods in the api:

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Semaphore.html

Some Semaphore Methods

Page 12: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Uses

• Limiting concurrent access to a resource, in general.• Limiting the number of created threads.• Limiting the number of concurrent connections.• Etc.

Page 13: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Code Example – In the Club• Groups of people asking for entrance permits to a club.

FiftyCentTheBouncer Club

5 entrance permits

Group1requests n1 entrance permits

Group2 requests n2 entrance permits

Group3 requests n3 entrance permits

Group4requests n4 entrance permits

Group5

requests n5 entrance permits

Page 14: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Callable

• java.util.concurrent.Callable :• Like Runnable, but:– Allows Threads to return values.– Allows Threads to throw exceptions.– Uses generics to define object types. – Class Header:

public class <threadName> implements Callable<returnObjectName>

– Required Functions:• public <returnObjectType> call()• Same purpose as Runnable’s run()

Page 15: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Futures• Used in combination with the Executor.• An object that represents the result of a Callable.

• Can retrieve the Callable’s result:– Using get() method– The result can be retrieved only when the computation has

completed.– get() blocks, until value can be retrieved.

• Allows cancellation of Thread execution.– Using cancel() method– Cannot cancel a completed Callable.

• Interface: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html

Page 16: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Code Example – The Price is Right• A game were contestants try to guess the price of an item,

given a max and a min value• . The contestant whose guess is closest to the actual price

wins.

ThePriceIsRightItem: Xerox Phaser 5500DN Workgroup Laser Printer.

Actual price: $500

Contestant1 makes a guess between $1 - $1000

Contestant2makes a guess between $1 - $1000

Contestant3makes a guess between $1 - $1000

Contestant4makes a guess between $1 - $1000

Contestant5

makes a guess between $1 - $1000

Page 17: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

• Create n Callables and save their futures in a collection.• While not all n values were retrieved:– Acquire a semaphore (a semaphore is released at the end of each

Callable)– Look for the Callable that finished, using the collection of futures.– Get the value returned by the callable that finished.– Set the found future to null in the collection, so it won’t be checked

again.

Page 18: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Notes

• Runnable, Callable are objects, they are not threads.• Threads receive these objects and run them.• Threads receive a reference to these objects. Threads do not create a new

copy of the runnable or the callable objects.• Having a stateful runnable/callable object (changes its own values) and

running more than one thread to it will cause problems if not synchronized!• Runnable objects cannot throw exceptions back to main. Run() method

does not throw Exception• Callable objects can throw exceptions back to main. Call() method throws

Exception.

Page 19: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Thread Cancellation• Thread t = new Thread(…);• How?

– t.stop() method. (deprecated)• Good? (doesn’t leave the objects in a stable state)

– Unsafe! – Releases all object locks instantly.

• Then, how?– By implementing a “shouldStop” method.– “shouldStop” checks a flag in the thread.– Case where a flag is true, thread stops working.

• Good?– Not always!– Thread might not take too long to stop:

• In case where the thread in sleep condition.

– Thread might not stop at all:• In case where the thread in wait() condition. And no notify() on the horizon.

Page 20: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

shouldStop Exampleclass Worker implements Runnable { private boolean fShouldStop ;

public Worker() {fShouldStop=false;

} public synchronized void stop() { fShouldStop = true; } public synchronized boolean shouldStop() { return fShouldStop; } public void run() { while (!this.shouldStop()){ doTheWork(); } System.out.println("stopping…"); }}

Page 21: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

interrupt()• The interrupt() mechanism.• Each thread stores an internal flag known as interrupt status.• Methods:

– t.isInterrupted() • Checks whether the thread is interrupted or not.

– t.interrupt():• If t is blocked (wait(), sleep()) then

– InterruptedException is thrown.– Forces the thread to wake up! From sleep or wait mode.

• Otherwise– isInterrupted() will return true.– Behaves the same as shouldStop.

• Note: – If InterruptedException is thrown, isInterrupted() will return false unless interrupt() is called again.

Page 22: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

interrupt() exampleclass Worker implements Runnable { public Worker() { }

public boolean condition() { return false; }

public synchronized void doSomeWork() { while (!this.condition() && !Thread.currentThread().isInterrupted()) { try { this.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // re-raise the interrupt. This is very important! break; // get out of the loop (and out of the method) } } }

public void run() { while (!Thread.currentThread().isInterrupted()){ doSomeWork(); } System.out.println("stopping ;)"); }}

Page 23: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

interrupt() example continued

• class Driver{public static void main(String[] args) {

Thread t = new Thread(new Worker());t.start();

try {Thread.sleep(100);

} catch (InterruptedException e) { }

t.interrupt();}

}

Page 24: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

Advanced Thread Synchronization Methods

Page 25: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

java.util.concurrent.CountDownLatch

• What?– A synchronization method.– Allows one or more threads to wait until other threads complete.

• How?– A CountDownLatch object is initialized with a starting value. – The await() method blocks until the current count reaches zero

due to invocations of the countDown() method in other threads.– After which all waiting threads are released and any subsequent

invocations of await return immediately. • Properties:

– The CountDownLatch cannot be reset. – This is a good practice for initialization/finalization purposes. – When we need to use some waiting point only once, the latch is

best to do the job.

Page 26: Practice Session 8 Blocking queues Producers-Consumers pattern Semaphore Futures and Callables Advanced Thread Synchronization Methods CountDownLatch Thread

• Example:– In multiplayer games you don’t want any player to start

until all players have joined. – This procedure works only once at the start of the game.

• API: – http://docs.oracle.com/javase/1.5.0/docs/api/java/util/

concurrent/CountDownLatch.html• Code Example: server waiting for clients to finish,

before it shuts down.– CountDownLatch