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

design patterns concurrency
SMART_READER_LITE
LIVE PREVIEW

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.


slide-1
SLIDE 1

Sebastian Graf, Oliver Haase

1

Design Patterns & Concurrency

slide-2
SLIDE 2

2

Expectations ?

...on the concurrency-part...

slide-3
SLIDE 3

3

Outline

  • f the concurrency part
  • I. Fundamentals
  • II. Concurrent Applications
  • III. Liveness, Performance and Hazards
  • IV. Advanced T
  • pics

All mapped on object-oriented programming with Java.

slide-4
SLIDE 4

4

Why?

slide-5
SLIDE 5

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
slide-6
SLIDE 6

6

Threads are everywhere

  • Garbage Collection
  • RMI Invocation (marshalling / unmarshalling)
  • Servlets

Importance of thread-safety is crucial!

slide-7
SLIDE 7

7

Threadsafe ?

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

slide-8
SLIDE 8

8

Thread-Unsafe !

slide-9
SLIDE 9

9

Threadsafe Impl.

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

slide-10
SLIDE 10

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.

slide-11
SLIDE 11

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); } }

slide-12
SLIDE 12

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); } }

slide-13
SLIDE 13

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); } }

slide-14
SLIDE 14

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); } } }

slide-15
SLIDE 15

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); } } }

slide-16
SLIDE 16

16

Poor concurrency

slide-17
SLIDE 17

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
slide-18
SLIDE 18

18

Amdahl's law in detail

  • P: Parts to be parallized
  • 1-P: Part not to be parallized
  • N: Number of Threads
slide-19
SLIDE 19

19

Scaling of Amdahl's Law

slide-20
SLIDE 20

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); } }

slide-21
SLIDE 21

21

Fix broken code

  • Do not share state variables across threads
  • Make sate variables immutable
  • Synchronizing access to shared state variables
slide-22
SLIDE 22

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

slide-23
SLIDE 23

23

Finally