Download presentation
Presentation is loading. Please wait.
1
8. Condition Objects Prof. O. Nierstrasz Selected material © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls
2
© Oscar Nierstrasz 2 Roadmap Condition Objects —Simple Condition Objects —The “Nested Monitor Problem” —Permits and Semaphores JUC (java.util.concurrent) Condition Objects
3
© Oscar Nierstrasz 3 Roadmap Condition Objects —Simple Condition Objects —The “Nested Monitor Problem” —Permits and Semaphores JUC (java.util.concurrent) Condition Objects
4
Pattern: Condition Objects Intent: Condition objects encapsulate the waits and notifications used in guarded methods. Applicability To simplify class design by off-loading waiting and notification mechanics. —Because of the limitations surrounding the use of condition objects in Java, in some cases the use of condition objects will increase rather than decrease design complexity! … © Oscar Nierstrasz Condition Objects 4
5
Pattern: Condition Objects Applicability … As an efficiency manoeuvre. —By isolating conditions, you can often avoid notifying waiting threads that could not possibly proceed given a particular state change. As a means of encapsulating special scheduling policies surrounding notifications, for example to impose fairness or prioritization policies. In the particular cases where conditions take the form of “permits” or “latches”. © Oscar Nierstrasz Condition Objects 5
6
© Oscar Nierstrasz Condition Objects 6 A client that awaits a condition blocks until another object signals that the condition now may hold. public interface Condition { public void await ();// wait for some condition public void signal ();// signal that condition } Cf. java.util.concurrent.locks.Condition Counter
7
© Oscar Nierstrasz Condition Objects 7 A Simple Condition Object We can encapsulate guard conditions with this class: public class SimpleConditionObject implements Condition { public synchronized void await () { try { wait(); } catch (InterruptedException ex) {} } public synchronized void signal () { notifyAll (); } NB: Careless use can lead to the “Nested Monitor Problem”
8
© Oscar Nierstrasz 8 Roadmap Condition Objects —Simple Condition Objects —The “Nested Monitor Problem” —Permits and Semaphores JUC (java.util.concurrent) Condition Objects
9
© Oscar Nierstrasz Condition Objects 9 The Nested Monitor problem We want to avoid waking up the wrong threads by separately notifying the conditions notMin and notMax: public class BoundedCounterNestedMonitorBAD extends BoundedCounterAbstract { protected Condition notMin = new SimpleConditionObject(); protected Condition notMax = new SimpleConditionObject(); public synchronized long value() { return count; }... Counter
10
© Oscar Nierstrasz Condition Objects 10 public synchronized void dec() { while (count == MIN) notMin.await();// wait till count not MIN if (count-- == MAX) notMax.signal(); } public synchronized void inc() {// can’t get in! while (count == MAX) notMax.await(); if (count++ == MIN) notMin.signal();// we never get here! }
11
© Oscar Nierstrasz Condition Objects 11 The Nested Monitor problem... Nested monitor lockouts occur whenever a blocked thread holds the lock for an object containing the method that would otherwise provide a notification to unblock the wait.
12
© Oscar Nierstrasz Condition Objects 12 Nested Monitors in FSP Nested Monitors typically arise when one synchronized object is implemented using another. Recall our one Slot buffer in FSP: Suppose we try to implement a call/reply protocol using a private instance of Slot: const N = 2 Slot = (put[v:0..N] -> get[v] -> Slot). ReplySlot=( put[v:0..N] -> my.put[v] -> ack -> ReplySlot | get -> my.get[v:0..N] -> ret[v] -> ReplySlot ). 01
13
© Oscar Nierstrasz Condition Objects 13 Nested Monitors in FSP... Our producer/consumer chain obeys the new protocol: 01 Producer = (put[0] -> ack ->put[1] -> ack ->put[2] -> ack -> Producer ). Consumer = ( get-> ret[x:0..N]->Consumer ). ||Chain = (Producer||ReplySlot||my:Slot||Consumer).
14
© Oscar Nierstrasz Condition Objects 14 Nested Monitors in FSP... But now the chain may deadlock: Progress violation for actions: {{ack, get}, my.{get, put}[0..2], {put, ret}[0..2]} Trace to terminal set of states: get Actions in terminal set: {} 01
15
© Oscar Nierstrasz Condition Objects 15 Solving the Nested Monitors problem You must ensure that: Waits do not occur while synchronization is held on the host object. —Leads to a guard loop that reverses the faulty synchronization Notifications are never missed. —The entire guard wait loop should be enclosed within synchronized blocks on the condition object. Notifications do not deadlock. —All notifications should be performed only upon release of all synchronization (except for the notified condition object). Helper and host state must be consistent. —If the helper object maintains any state, it must always be consistent with that of the host —If it shares any state with the host, access must be synchronized.
16
© Oscar Nierstrasz Condition Objects 16 Example solution public class BoundedCounterCondition extends BoundedCounterAbstract {public void dec() {// not synched! boolean wasMax = false;// record notification condition synchronized(notMin) {// synch on condition object while (true) {// new guard loop synchronized(this) { if (count > MIN) {// check and act wasMax = (count == MAX); count--; break; } notMin.await();// release host synch before wait } if (wasMax) notMax.signal();// release all syncs! }... }
17
© Oscar Nierstrasz 17 Roadmap Condition Objects —Simple Condition Objects —The “Nested Monitor Problem” —Permits and Semaphores JUC (java.util.concurrent) Condition Objects
18
© Oscar Nierstrasz Condition Objects 18 Pattern: Permits and Semaphores Intent: Bundle synchronization in a condition object when synchronization depends on the value of a counter. Applicability When any given await may proceed only if there have been more signals than awaits. —I.e., when await decrements and signal increments the number of available “permits”. You need to guarantee the absence of missed signals. —Unlike simple condition objects, semaphores work even if one thread enters its await after another thread has signalled that it may proceed (!) The host classes can arrange to invoke Condition methods outside of synchronized code.
19
Permits and Semaphores — design steps Define a class implementing Condition that maintains a permit count, and immediately releases await if there are already enough permits. —e.g., BoundedCounter © Oscar Nierstrasz Condition Objects 19
20
Example © Oscar Nierstrasz Condition Objects 20 public class Permit implements Condition { private int count; Permit(int init) { count = init; } public synchronized void await() { while (count == 0) { try { wait(); } catch(InterruptedException ex) { }; } count --; } public synchronized void signal() { count ++; notifyAll(); } Counter
21
© Oscar Nierstrasz Condition Objects 21 Design steps... As with all kinds of condition objects, their clients must avoid invoking await inside of synchronized code. —You can use a before/after design of the form: class Host { Condition aCondition;... public method m1() { aCondition.await();// not synced doM1();// synced for each Condition c enabled by m1() c.signal();// not synced } protected synchronized doM1() {... } }
22
Using permits © Oscar Nierstrasz Condition Objects 22 public class Building{ Permit permit; Building(int n) { permit = new Permit(n); } void enter(String person) { // NB: unsynchronized permit.await(); System.out.println(person + " has entered the building"); } void leave(String person) { System.out.println(person + " has left the building"); permit.signal(); } Counter
23
Using permits © Oscar Nierstrasz Condition Objects 23 public static void main(String[] args) { Building building = new Building(3); enterAndLeave(building, "bob"); enterAndLeave(building, "carol");... } private static void enterAndLeave(final Building building, final String person) { new Thread() { public void run() { building.enter(person); pause(); building.leave(person); } }.start(); } bob has entered the building carol has entered the building ted has entered the building bob has left the building alice has entered the building ted has left the building carol has left the building elvis has entered the building alice has left the building elvis has left the building
24
© Oscar Nierstrasz Condition Objects 24 Variants Permit Counters: (Counting Semaphores) Just keep track of the number of “permits” Can use notify instead of notifyAll if class is final Fair Semaphores: Maintain FIFO queue of threads waiting on a SimpleCondition Locks and Latches: Locks can be acquired and released in separate methods Keep track of thread holding the lock so locks can be reentrant! A latch is set to true by signal, and always stays true
25
© Oscar Nierstrasz Condition Objects 25 Semaphores in Java public class Semaphore {// simple version private int value; public Semaphore (int initial) { value = initial; } synchronized public void up() {// AKA V ++value; notify();// wake up just one thread! } synchronized public void down() {// AKA P while (value== 0) { try { wait(); } catch(InterruptedException ex) { }; } --value; } Cf. java.util.concurrent.Semaphore Counter
26
© Oscar Nierstrasz Condition Objects 26 Using Semaphores public class BoundedCounterSem extends BoundedCounterAbstract { … protected Semaphore mutex, full, empty; BoundedCounterVSem() { mutex = new Semaphore(1); full = new Semaphore(0);// number of items empty = new Semaphore(MAX-MIN); // number of slots } public long value() { mutex.down(); // grab the resource long val = count; mutex.up(); // release it return val; } public void inc() { empty.down(); // grab a slot mutex.down(); count ++; mutex.up(); full.up(); // release an item } … Counter
27
© Oscar Nierstrasz Condition Objects 27 Using Semaphores... These would cause a nested monitor problem!... public void BADinc() { mutex.down(); empty.down(); // locks out BADdec! count ++; full.up(); mutex.up(); } public void BADdec() { mutex.down(); full.down(); // locks out BADinc! count --; empty.up(); mutex.up(); }
28
© Oscar Nierstrasz 28 Roadmap Condition Objects —Simple Condition Objects —The “Nested Monitor Problem” —Permits and Semaphores —Using Semaphores JUC (java.util.concurrent) Condition Objects
29
© Oscar Nierstrasz Condition Objects 29 java.util.concurrent Executors —Executor —ExecutorService —ScheduledExecutorService —Callable —Future —ScheduledFuture —Delayed —CompletionService —ThreadPoolExecutor —ScheduledThreadPoolExecutor —AbstractExecutorService —Executors —FutureTask —ExecutorCompletionService Queues —BlockingQueue —ConcurrentLinkedQueue —LinkedBlockingQueue —ArrayBlockingQueue —SynchronousQueue —PriorityBlockingQueue —DelayQueue Concurrent Collections —ConcurrentMap —ConcurrentHashMap —CopyOnWriteArray{List,Set} Synchronizers —CountDownLatch —Semaphore —Exchanger —CyclicBarrier Locks: java.util.concurrent.locks —Lock —Condition —ReadWriteLock —AbstractQueuedSynchronizer —LockSupport —ReentrantLock —ReentrantReadWriteLock Atomics: java.util.concurrent.atomic —Atomic[Type] —Atomic[Type]Array —Atomic[Type]FieldUpdater —Atomic{Markable,Stampable}Reference © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls
30
© Oscar Nierstrasz Condition Objects 30 © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls Key Functional Groups Executors, Thread pools and Futures —Execution frameworks for asynchronous tasking Concurrent Collections: —Queues, blocking queues, concurrent hash map, … —Data structures designed for concurrent environments Locks and Conditions —More flexible synchronization control —Read/write locks Synchronizers: Semaphore, Latch, Barrier —Ready made tools for thread coordination Atomic variables —The key to writing lock-free algorithms
31
© Oscar Nierstrasz Condition Objects 31 © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls The Executor Framework Framework for asynchronous task execution Standardize asynchronous invocation —Framework to execute Runnable and Callable tasks – Runnable: void run() – Callable : V call() throws Exception Separate submission from execution policy —Use anExecutor.execute(aRunnable) —Not new Thread(aRunnable).start() Cancellation and shutdown support Usually created via Executors factory class —Configures flexible ThreadPoolExecutor —Customize shutdown methods, before/after hooks, saturation policies, queuing
32
© Oscar Nierstrasz Condition Objects 32 © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls Executor Decouple submission policy from task execution Code which submits a task doesn't have to know in what thread the task will run —Could run in the calling thread, in a thread pool, in a single background thread (or even in another JVM!) —Executor implementation determines execution policy – Execution policy controls resource utilization, overload behavior, thread usage, logging, security, etc – Calling code need not know the execution policy public interface Executor { void execute(Runnable command); }
33
© Oscar Nierstrasz Condition Objects CP 9.33 ExecutorService Adds lifecycle management ExecutorService supports both graceful and immediate shutdown public interface ExecutorService extends Executor { void shutdown(); List shutdownNow(); boolean isShutdown(); boolean isTerminated(); boolean awaitTermination(long timeout, TimeUnit unit); //... } Useful utility methods too — T invokeAny(Collection > tasks) – Executes the given tasks returning the result of one that completed successfully (if any) —Others involving Future objects © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls
34
© Oscar Nierstrasz Liveness and Asynchrony 34 FutureTask public FutureTask service (final int n) { FutureTask future = new FutureTask ( new Callable () { public Integer call() { return new Integer(fibonacci(n)); } }); new Thread(future).start(); // or use an Executor return future; } JUC provides a generic implementation of Futures, parameterized by Callable or Runnable services. Asynchrony
35
© Oscar Nierstrasz Condition Objects CP 9.35 © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls Creating Executors Sample Executor implementations from Executors newSingleThreadExecutor —A pool of one, working from an unbounded queue newFixedThreadPool(int N) —A fixed pool of N, working from an unbounded queue newCachedThreadPool —A variable size pool that grows as needed and shrinks when idle newScheduledThreadPool —Pool for executing tasks after a given delay, or periodically
36
© Oscar Nierstrasz Condition Objects CP 9.36 Locks and Synchronizers java.util.concurrent provides generally useful implementations —ReentrantLock, ReentrantReadWriteLock —Semaphore, CountDownLatch, Barrier, Exchanger —Should meet the needs of most users in most situations – Some customization possible in some cases by subclassing Otherwise AbstractQueuedSynchronizer can be used to build custom locks and synchronizers —Within limitations: int state and FIFO queuing Otherwise build from scratch —Atomics —Queues —LockSupport for thread parking/unparking © 2005 Bowbeer, Goetz, Holmes, Lea and Peierls
37
© Oscar Nierstrasz Condition Objects CP 9.37 What you should know! What are “condition objects”? How can they make your life easier? Harder? What is the “nested monitor problem”? How can you avoid nested monitor problems? What are “permits” and “latches”? When is it natural to use them? How does a semaphore differ from a simple condition object? Why (when) can semaphores use notify() instead of notifyAll()?
38
© Oscar Nierstrasz Condition Objects CP 9.38 Can you answer these questions? Why doesn’t SimpleConditionObject need any instance variables? What is the easiest way to avoid the nested monitor problem? What assumptions do nested monitors violate? How can the obvious implementation of semaphores (in Java) violate fairness? How would you implement fair semaphores?
39
License © Oscar Nierstrasz 39 Attribution-ShareAlike 2.5 You are free: to copy, distribute, display, and perform the work to make derivative works to make commercial use of the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor. Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. For any reuse or distribution, you must make clear to others the license terms of this work. Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. http://creativecommons.org/licenses/by-sa/2.5/ Condition Objects
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.