1 / 24

6894 · workshop in software design lecture 6 · october 19, 1998 · concurrent design patterns

6894 · workshop in software design lecture 6 · october 19, 1998 · concurrent design patterns. background to lea’s book. book [Doug Lea, 97] Concurrent Programming in Java: Design Principles & Patterns concurrency focus on problems with natural concurrency; maybe just one CPU

jmagdalena
Télécharger la présentation

6894 · workshop in software design lecture 6 · october 19, 1998 · concurrent design patterns

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 6894 · workshop in software designlecture 6 · october 19, 1998 · concurrent design patterns

  2. background to lea’s book • book • [Doug Lea, 97] Concurrent Programming in Java: Design Principles & Patterns • concurrency • focus on problems with natural concurrency; maybe just one CPU • compare to parallel programming • inherently sequential programs, many CPUs • additional specialized techniques needed for • distributed systems, realtime systems, databases • design • focus on structural design issues • not details of algorithms or protocols • patterns • motivation similar to GOF • explain and classify common techniques, with emphasis on terminology • more concerned with basics of achieving safety and liveness • less concern for flexibility • subclassing often mentioned (but more a problem than a solution?)

  3. safety & liveness • two aspects of interference • safety: nothing bad happens • usually first concern • liveness: something good happens • often critical too: flood gates fail? • conflicting • most of the things that improve safety damage liveness, and vv • so many of Lea’s liveness patterns are really just ways to adjust safety patterns • finite & infinite • safety problems can be observed after a finite time • at 10 o’clock the train crashed • liveness problems may require infinite time • process may be unblocked just after you check! • but in practice, most liveness problems are very finite • most users know when an application is stuck in a loop

  4. safety • safety problems • arise because of lack of synchronization • manifestations • events happen out of order • garbage results are produced • values are read that were never written • races • different schedulings give different outcomes • never assume thread with less computation to do will finish first! • often cause safety violations • make testing and debugging hard • example • textarea.display (“goodbye”); • textarea.display (“hello”); • outcome: “helgoolodbye”

  5. liveness • reasons why a thread may not be live • contention or ‘starvation’ • another thread has taken over CPU resources • dormancy • wait without notify, suspend without resume • a simple coding error • deadlock • two threads in vicious cycle trying to access a lock • premature termination • killed by stop, eg • thread groups help • liveness is a global property • can design a component to be safe in all contexts • but hard to one live in all contexts • two components always live in other contexts may fail when run together

  6. liveness example • code sample • class Document ( Document other_part; • synchronized void print () { System.out.println (“first line”); … System.out.println (“last line”); } • synchronized void printAll () { other_part.print (); print (); } } • does this work? other_part DOCUMENT

  7. deadlock! • thread 1 thread 2 • letter.printAll • letter now locked • enclosure.printAll • enclosure now locked • letter.other_part.print • waiting for enclosure • enclosure.other_part.print • waiting for letter

  8. approaches to ensuring safety & liveness (1) • proof • develop a mathematical argument for why program works • check by social consent or use theorem prover • advantages • gives lots of insight, may help improve design • good for subtle algorithms (abstract, and amortized over many uses) • disadvantages • exhorbitant cost, proofs not reusable • model checking • extract a state machine from the code (by hand or semiautomatically) • specify safety and liveness properties in a temporal logic • run model checker to find bugs • advantages • more cost-effective than proof • properties can be reused • disadvantages • gives little insight, confidence can be misleading

  9. approaches to ensuring safety & liveness (2) • testing • run program and check properties as it executes • new, more sophisticated dynamic analyzers may test ‘all’ paths (eg, Rivet) • advantages • no extraction of model needed • to some extent, can do without source code • disadvantages • lower coverage than model checking • won’t work on partial programs • correctness by construction • establish standard policies & structures that guarantee properties • constrain design within these bounds • advantages • reuse of design expertise • reliable, practical, maintainable • disadvantages • not so flexible

  10. java mechanisms: thread control • elements • java.lang.Thread to initiate and control new activities • keywords synchronized and volatile, used to control code in objects in >1 thread • methods wait, notify and notifyAll, defined in java.lang.Object • thread control • to create a thread • Runnable x = …; Thread t = new Thread (x); t.start () • to terminate a thread • x.run returns, or t.stop () • to temporarily halt a thread • t.suspend (), t.resume () • to suspend thread for given time • t.sleep (milis) • to wait for a thread to complete • t.join () • to check if a thread has started but not terminated • t.isAlive ()

  11. java mechanisms: locking • locking • synchronized void foo (…) • foo cannot be executed while another synchronized method of this is running • but not atomic! unsynchronized methods can run • synchronized (foo) {…} • block cannot be executed while another thread has the lock on object foo • volatile instance variables • a compiler optimization: • t = v; … (no assignments to v) … ; u = v; • assume v has same value at both assignments • not valid in multithreaded code • marking v as volatile disables this optimization

  12. java mechanisms: notification • wait, notify, notifyAll • o.wait (), o.notify (), o.notifyAll • may only be invoked by thread with lock on o • o.wait • suspends current thread • puts thread in wait queue for o • releases sync lock for o • o.notify • some thread t in the wait queue for o is removed • t blocks until lock on o is released • t acquires lock and continues at wait point • o.notifyAll • like notify, but for all threads in queue • should generally use rather than notify

  13. lea’s patterns • programming idioms • how to use basic mechanisms • at level of individual code statements • eg, when to mark a variable as volatile • design patterns • how to assemble components • at granularity level of GOF patterns • eg, structural containment, completion callback • architectural styles • general organization schemes and policies • at granularity level of Garlan/Shaw architectures • eg, concurrency control schemes • online supplement • http://gee.cs.oswego.edu/dl/cpj • collects patterns from book in GOF style • but generally lower level than GOF patterns

  14. immutability • basic idea • easiest way to avoid undesirable state changes • use objects that never change state! • eg, use String in place of StringBuffer • to make an object immutable • override Object.hashCode and Object.equals • methods: constructors, but not mutators • might make class final • partially immutable objects • can drop synchronization for methods that read immutable components • semi-immutable variables • variables that change value once • boolean latches, fields that get set from null to a fixed value • can exploit special constructions • eg, value can’t change between test and action

  15. fully synchronized objects • synchronize every method of class • then locally sequential behaviour • each object does only one thing at a time • liveness concerns motivate weaking sync • make accessors unsynchronized (be careful!) • exploit immutability of instance vars • split locks or classes • example • Shape object has x, y, width and height vars • access to each {x, y} and {width, height} must be synchronized, but OK to access {x, height} • class splitting • form two classes, Location and Dimension, with synchronized methods • containing class, Shape, has unsynchronized methods • lock splitting • introduce a lock for each set of instance vars • location method now has block synchronized on location_lock

  16. CLIENT ? RESOURCE structural containment • basic idea • achieve sync structurally by avoiding shared variables • compared to fully synchronized classes • less prone to liveness failures and more efficient • but very limited • class structure • client methods are synchronized • resource methods are unsynchronized • managing ownership • fixed: never changes • exclusive resource: changes owner, but at most one • basic ops: acquire, forget, give, take, exchange • protocol: eg, ring

  17. asynchronous invocation • basic idea • make message passing really message passing! • client need not wait for service to complete • example • in Observer pattern, notification can cause deadlock • subject is waiting to notify observer • observer is waiting to get state from subject • so make notification asynchronous • strategies • direct invocation • normal invocation, but in unsynchronized method • host object can ‘continue’ (in another thread) • thread-based • perform invocation within a new thread • command-based • create message or event object and pass to other object that executes it

  18. optimistic methods • basic idea • method attempts action, assuming success • if action fails, rolls back and cancels • failure may be due to • bad interleaving of threads • network failure or machine down • … programming error • why? • in databases: less locking, better performance • in distributed system, failure impossible to predict • design issues • how to rollback state • how to identify failures • typical elements • transaction ids, timestamps • make backup copies • commit protocol

  19. concurrency control • motivation • want to separate • synchronization & control • base mechanisms • reuse of ‘ground’ classes • safety and liveness properties • guaranteed by CC layer • patterns • Subclassing • overriding method adds sync (& maybe tracks extra state to do so) • Readers & Writers • partition methods into read & write • superclass tracks #reading/writing threads • read/write methods are hooks: abstract methods implemented in subclass • Adapters • control passes through synchronized method that delegates to unsynchronized method • Acceptors

  20. read-only adapter • basic idea • adapter provides immutable view of mutable object • an example of concurrency control • layering sync mechanism over ‘ground’ object • alternative • view through immutable interface • (but allows client to cast to mutable class) • notes • client is not protected from changes, only from making changes! • so object does not appear to be immutable CLIENT IMMUT MUT CLIENT MUT IMMUT

  21. acceptors • basic idea • concurrency control by exploiting reflection with meta-objects • pass around representations of messages • Acceptor is object that accepts generic message • public interface Acceptor { public void accept (MessageType msg); } • other names for accept: handle, action, perform, post, execute • examples of messages • instance of java.awt.Event • Listener is a kind of Acceptor • instance of Runnable class: execution by invoking run • instance of Class class: execution by creation of new object

  22. services • common thread idioms • Command: service that never conveys result to client • Completion: finding out if a service is done • Group Services: allocate service to several threads, invisible to client • … not directly supported by Java

  23. futures • motivation • client needs to know when service completes • want to avoid polling service • join • block until service thread completes, then use result • serviceThread.join(); • result = service.result (); • idea of futures • a programming language feature • call to service is asynchronous • immediately returns result • no blocking until result is used • can simulate in Java • service maintains reference to its thread • join is encapsulated in call to result method

  24. completion callback • motivation • want something more flexible than join-based technique • eg, >1 action on completion • structure • Client passes itself to Service • when Service is done, it calls • client.done () • client.failed () • etc CLIENT SERVICE SERVICE-CLIENT

More Related