design patterns concurrency
play

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

Design Patterns & Concurrency Sebastian Graf, Oliver Haase 1 Montag, 25. April 2011 Fundamentals 2 Montag, 25. April 2011 Recap Threadsafety What is threadsafety? How can threadsafety be ensured? Amdahls Law 3 Montag,


  1. Design Patterns & Concurrency Sebastian Graf, Oliver Haase 1 Montag, 25. April 2011

  2. Fundamentals 2 Montag, 25. April 2011

  3. Recap ‣ Threadsafety • What is threadsafety? • How can threadsafety be ensured? ‣ Amdahls Law 3 Montag, 25. April 2011

  4. Recap Threadsafety public final class HitCounter { /** internal state counter variable */ private int counter = 0; /** * Getting the counter right now * @return the counts */ public final int getCounter() { return this.counter; } /** * Counting multiple values * @param countsToAdd numbers to add to the counter */ public final void increment(final int countsToAdd) { counter = counter + countsToAdd; } /** Counting by one */ public final void incrementByOne() { increment(1); } } 4 Montag, 25. April 2011

  5. Recap Threadsafety public final class SynchronizedCounter { /** internal state counter variable */ private int counter = 0; /** * Getting the counter right now * @return the counts */ public synchronized final int getCounter() { return this.counter; } /** * Counting multiple values * @param countsToAdd numbers to add to the counter */ public synchronized final void increment(final int countsToAdd) { counter = counter + countsToAdd; } /** Counting by one */ public final void incrementByOne() { increment(1); } } 5 Montag, 25. April 2011

  6. Recap Threadsafety import java.util.List; public final class ListSum { /** * Summing multiple variables * * @param multiple * variables * @return the sum of the variables */ public final int sum(final List<Integer> factors) { int sum = 0; for (final int number : factors) { sum = sum + number; } return sum; } } 6 Montag, 25. April 2011

  7. Recap Threadsafety public final class IDHandler { /**Local set of ids*/ private String[] ids = { "e634g", "6fhg4", "hd4fg", "dgf53" }; /**Getting the ids. * * @return the ids */ public String[] getIDs() { return ids; } } 7 Montag, 25. April 2011

  8. Recap Threadsafety public final class IDHandler { /**Local set of ids*/ private final List<String >ids = new ArrayList()<String>; public IDHandler() { ids.add("e634g"); ids.add("6fhg4"); ids.add("hd4fg"); ids.add("dgf53"); } /**Getting the ids. * * @return the ids */ public String[] getIDs() { return ids.toArray(new String[4]); } } 8 Montag, 25. April 2011

  9. Threadsafe? public class ReadyStater { private static boolean ready; private static int number; private static class ReaderThread extends Thread { public void run() { while (!ready) Thread.yield(); System.out.println(number); } } public static void main(String[] args) { new ReaderThread().start(); number = 42; ready = true; } } 9 Montag, 25. April 2011

  10. Locking & Visibility 10 Montag, 25. April 2011

  11. Difference regarding visibility @NotThreadSafe public class MutableInteger { private int value; public int get() { return value; } public void set(int value) { this.value = value; } } @NotThreadSafe public class MutableInteger { private long value; public long get() { return value; } public void set(long value) { this.value = value; } } 11 Montag, 25. April 2011

  12. Always Synchronize? public class MutableInteger { private long value; public synchronized long get() { return value; } public synchronized void set(long value) { this.value = value; } } public class MutableInteger { private volatile long value; public long get() { return value; } public void set(long value) { this.value = value; } } 12 Montag, 25. April 2011

  13. Volatile VS Synchronize Volatile Synchonize ‣ No Locking ‣ Locking • no synchronization • synchronization ‣ visibility ‣ visibility ‣ Usage: ‣ Usage: • using if only one thread • guarding multiple variables updates value OR (invariants) • value is not participating • accessing within multiple to invariants OR threads • any other reason 13 Montag, 25. April 2011

  14. Publishing and Escaping ‣ Publishing: Making a variable visible out of its current scope ‣ Escaping: Doing the same by accident public final class IDHandler { /**Local set of ids*/ private String[] ids = { "e634g", "6fhg4", "hd4fg", "dgf53" }; /**Getting the ids. * * @return the ids */ public String[] getIDs() { return ids; } } 14 Montag, 25. April 2011

  15. Escaping in Construtor public class ThisEscape { public ThisEscape(EventSource source) { source.registerListener( new EventListener() { public void onEvent(Event e) { doSomething(e); } }); } } 15 Montag, 25. April 2011

  16. Safe Construction Process Do not allow to escape this during construction. public class SafeListener { private final EventListener listener; private SafeListener() { listener = new EventListener() { public void onEvent(Event e) { doSomething(e); } }; } public static SafeListener newInstance(EventSource source) { SafeListener safe = new SafeListener(); source.registerListener(safe.listener); return safe; } } 16 Montag, 25. April 2011

  17. Further techniques to ensure thread safety ‣ Confinement ‣ Immutability ‣ Publication ‣ Design ‣ Documentation 17 Montag, 25. April 2011

  18. Confinement ‣ Thread Confinement Binding an object to exactly one thread (which cannot be enforced by the JVM) ‣ Ad-hoc Confinement Responsibility of maintaining thread safety is on implementation side (which is mostly fragile) ‣ Stack Confinement Object bound to local variables only (happening in methods) ‣ ThreadLocal private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>() { public Connection initialValue() { return DriverManager.getConnection(DB_URL); } }; public static Connection getConnection() { return connectionHolder.get(); } 18 Montag, 25. April 2011

  19. Immutability Criterias for Immutability ‣ State cannot be modified after construction ‣ All fields are final ‣ properly constructed Immutable Objects are always thread-safe! public final class ThreeStooges { private final Set<String> stooges = new HashSet<String>(); public ThreeStooges() { stooges.add("Moe"); stooges.add("Larry"); stooges.add("Curly"); } public boolean isStooge(String name) { return stooges.contains(name); } } 19 Montag, 25. April 2011

  20. Immutability and Publishing @Immutable class OneValueCache { private final BigInteger lastNumber; private final BigInteger[] lastFactors; public OneValueCache(BigInteger i, BigInteger[] factors) { lastNumber = i; lastFactors = Arrays.copyOf(factors, factors.length); } public BigInteger[] getFactors(BigInteger i) { if (lastNumber == null || !lastNumber.equals(i)) return null; else return Arrays.copyOf(lastFactors, lastFactors.length); } } @ThreadSafe public class VolatileCachedFactorizer implements Servlet { private volatile OneValueCache cache = new OneValueCache(null, null); public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = cache.getFactors(i); if (factors == null) { factors = factor(i); cache = new OneValueCache(i, factors); } encodeIntoResponse(resp, factors); } } 20 Montag, 25. April 2011

  21. Publishing of data public Holder holder; public void initialize() { holder = new Holder(42); } public class Holder { private int n; public Holder(int n) { this.n = n; } public void assertSanity() { if (n != n) throw new AssertionError("This statement is false."); } } 21 Montag, 25. April 2011

  22. Safe publication idioms ‣ Initialize objects references from a static initializer ‣ Storing a reference into a volatile or AtomicReference ‣ Storing a reference into a final field of a proper constructed object ‣ Guard the field that stores the object with a lock Publication requirements ‣ Immutable objects: can be published with any mechanism ‣ Effectively immutable objects: must be published safely ‣ Mutable objects: must be published safely and be guared by a lock 22 Montag, 25. April 2011

  23. Useful policies for sharing objects ‣ Thread-confined: Object is owned exclusively by one thread ‣ Shared read-only: Object can be accessed concurrently by multiple threads without additional synchronization ‣ Shared thread-safe: Synchronization on object is handled internally. ‣ Guarded: Access to the object only possible when given lock held including encluding other thread-safe objects 23 Montag, 25. April 2011

  24. Designing Objects Identify the variables that form the object's state; • Identify the invariants that constrain the state variables; • Establish a policy for managing concurrent access to the object's state 24 Montag, 25. April 2011

  25. States? State of an object includes state of all fields ‣ primitive: simple ‣ n -primitives: n -tuple of the fields ‣ LinkedList: all linked nodes Stay aware of pre-/postconditions and invariants: Synchronization-Policy 25 Montag, 25. April 2011

  26. Thread-Safety redefined Making a class thread-safe means ensuring that its invariants hold under concurrent access; this requires reasoning about its state @ ThreadSafe public final class Counter { @GuardedBy("this") private long value = 0; public synchronized long getValue() { return value; } public synchronized long increment() { if (value == Long.MAX_VALUE) throw new IllegalStateException("counter overflow"); return ++value; } } 26 Montag, 25. April 2011

Recommend


More recommend