design patterns concurrency
play

Design Patterns & Concurrency Sebastian Graf, Oliver Haase 1 - PowerPoint PPT Presentation

Design Patterns & Concurrency Sebastian Graf, Oliver Haase 1 Expectations ? ...on the concurrency-part... 2 Outline of the concurrency part I. Fundamentals II. Concurrent Applications III. Liveness, Performance and Hazards IV.


  1. Design Patterns & Concurrency Sebastian Graf, Oliver Haase 1

  2. Expectations ? ...on the concurrency-part... 2

  3. Outline of the concurrency part I. Fundamentals II. Concurrent Applications III. Liveness, Performance and Hazards IV. Advanced T opics All mapped on object-oriented programming with Java. 3

  4. Why? 4

  5. Why? ‣ More responsive programs due to less blocking ‣ Exploiting multi-processor architectures ‣ T ask-oriented working (e.g. like in Servlets, RMI) ‣ Simply handling of asynchronous events 5

  6. Threads are everywhere ‣ Garbage Collection ‣ RMI Invocation (marshalling / unmarshalling) ‣ Servlets Importance of thread-safety is crucial! 6

  7. Threadsafe ? public class Sequence { private int value; /** Returns a unique value. */ public int getNext() { return value++; } } 7

  8. Thread-Unsafe ! 8

  9. Threadsafe Impl. @ThreadSafe public class Sequence { @GuardedBy("this") private int nextValue; public synchronized int getNext() { return nextValue++; } } 9

  10. Definition of Threadsafety Managing access to state, in particular to shared, mutable state (directly to member- variables of one class) with ‣ Atomic change of state ‣ Invariants, Pre- /Postconditions ‣ … Providing any necessary synchronization so that the client needs no own one. 10

  11. Simple Example public class StatelessFactorizer implements Servlet { public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); encodeIntoResponse(resp, factors); } } 11

  12. State variable example public class CountingFactorizer implements Servlet { private long count = 0; public long getCount() { return count; } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); ++count; encodeIntoResponse(resp, factors); } } 12

  13. Thread-safe state variable example public class CountingFactorizer implements Servlet { private final AtomicLong count = new AtomicLong(0); public long getCount() { return count.get(); } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); count.incrementAndGet(); encodeIntoResponse(resp, factors); } } 13

  14. Next one... public class UnsafeCachingFactorizer implements Servlet { private final AtomicReference<BigInteger> lastNumber = new AtomicReference<BigInteger>(); private final AtomicReference<BigInteger[]> lastFactors = new AtomicReference<BigInteger[]>(); public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); if (i.equals(lastNumber.get())) encodeIntoResponse(resp, lastFactors.get() ); else { BigInteger[] factors = factor(i); lastNumber.set(i); lastFactors.set(factors); encodeIntoResponse(resp, factors); } } } 14

  15. One Solution... public class SynchronizedFactorizer implements Servlet { @GuardedBy("this") private BigInteger lastNumber; @GuardedBy("this") private BigInteger[] lastFactors; public synchronized void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); if (i.equals(lastNumber)) encodeIntoResponse(resp, lastFactors); else { BigInteger[] factors = factor(i); lastNumber = i; lastFactors = factors; encodeIntoResponse(resp, factors); } } } 15

  16. Poor concurrency 16

  17. Excursion, Amdahl's Law “For the past thirty years, computer performance has been driven by Moore’s Law; from now on, it will be driven by Amdahl’s Law. [...]” -- Doron Rajwan, Research Scientist, Intel Corp 17

  18. Amdahl's law in detail ‣ P: Parts to be parallized ‣ 1-P: Part not to be parallized ‣ N: Number of Threads 18

  19. Scaling of Amdahl's Law 19

  20. One better solution public class CachedFactorizer implements Servlet { @GuardedBy("this") private BigInteger lastNumber; @GuardedBy("this") private BigInteger[] lastFactors; @GuardedBy("this") private long hits; @GuardedBy("this") private long cacheHits; public synchronized long getHits() { return hits; } public synchronized double getCacheHitRatio() { return (double) cacheHits / (double) hits; } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = null; synchronized (this) { ++hits; if (i.equals(lastNumber)) { ++cacheHits; factors = lastFactors.clone(); } } if (factors == null) { factors = factor(i); synchronized (this) { lastNumber = i; lastFactors = factors.clone(); } } encodeIntoResponse(resp, factors); } } 20

  21. Fix broken code ‣ Do not share state variables across threads ‣ Make sate variables immutable ‣ Synchronizing access to shared state variables 21

  22. But... ‣ Do not serialize heavy computations ‣ Remember Amdahl's law ‣ Think about what needs to be parallized from the point of view of program correctness 22

  23. Finally 23

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend