Concurrency Patterns David Kemp Melbourne Patterns Group March 2010 Some rights reserved:  Creative Commons Attribution-Noncommercial-Share Alike http://creativecommons.org/licenses/by-nc-sa/3.0/
Concurrency: what and why?
Thread Thread Stack Code Heap Stack
Issues
Race Conditions public class BankAccount { private int balance; public void adjustBalance(int amount) { balance = balance + amount; } ... }
Memory Consistency (A) Initially Thread B Instructions may be re-ordered a = true; b = true; return !b | a; boolean a = false; boolean b = false; Thread A Possible for Thread B to see  b  as true before  a  is true.
Memory Consistency (B) Initially Thread B Partially constructed objects can be visible object = new MyClass(); if (object != null) object.doSomething(); MyClass object = null; Thread A object  may not be in a consistent state in thread B
If Possible: Avoid Concurrency!!
Concurrency Primitives
Threads (in Java) Runnable runnable = new MyRunnable();  Thread thread = new Thread(runnable); thread.start(); interface Runnable { void run(); } Looks strangely like the command pattern (covered last month). The Java ExecutorService interface is even more like the Command Pattern.
Mutex (Mutual Exclusion Lock)
Mutexes can fix race conditions public class BankAccount { Object lock = new Object(); int balance; public void adjustBalance(int amount) { synchronize(lock)  { balance = balance + amount; } }
Mutexes can fix Memory Consistency Initially Thread B synchronize(lock) {  a = true; b = true; } synchronize(lock) {  return !b | a; } Object lock = new Object(); boolean a = false; boolean b = false; Thread A Must use the same lock! Can also fix some memory consistency problems using the volatile keyword.
If you need clever analysis to show thread safety, then it is either broken now, or will be broken by some future maintainer!!!!
Other Concurrency Abstractions Condition Variables Semaphores. Latches. Barriers. Futures. Read/Write Locks. Blocking Queues. Exchangers. Threadpools. Atomic Compare-And-Set
Some Patterns
Fully Synchronized Objects Photo by Kevin Hamm. Some rights reserved. See:  http://www.flickr.com/photos/krhamm/171302278/in/set-72157594171880205/
Fully Synchronized Object All methods on a fully synchronized object are synchronized on a single lock.
Resource Ordering Image by  Benjamin D. Esham for the Wikimedia Commons. Some rights reserved. See:  http://en.wikipedia.org/wiki/File:Dining_philosophers.png/
Copy-on-write
Passing immutable objects as messages between threads. Concurrent modification ceases to be a problem!
Partitioning
Double Check Locking Used for lazy initialization Photo by Kirainet. Some rights reserved. See:  http://www.flickr.com/photos/torek/2467519466/
Double Check Locking Easy to stuff up!!!
Double Check Locking Was not possible in Java before 1.5. Locks have become cheap, and so double-check not so useful. Usually better to use static initialization anyway. Was unreliable in C++/Posix threads when I last looked. Find out if it works in your language/platform before using!!
Double Check Locking But it is a nice demonstration of some concurrency issues
Double check locking (Warning: did not work before Java 1.5) volatile  Properties properties = null; final Object lock = new Object(); public Properties getProperties() { if (properties == null) { synchronized  (lock) { if (properties == null) { tmp = new Properties(); tmp.load(inputStream); properties = tmp; } } } return properties; } Possibly broken! Definitely Brittle!
Lock-free Queue
Lock Free Queue Queue Dummy Node Real Head Node Tail Penultimate node Head Tail : Might point to last or second last node! References are all updated using the Atomic Test-And-Set.
References M. Ben-Ari,  Principles of Concurrent Programming,  Prentice Hall. Doug Lea,  Concurrent Programming in Java Second Edition. Design Principles and Patterns , Addison-Wesley. Brian Goetz,  Java Concurrency in Practice . Pearson Education. Software Engineering Radio, Episodes 12, 19, and 29. http://www.se-radio.net/

Concurrency Patterns

  • 1.
    Concurrency Patterns DavidKemp Melbourne Patterns Group March 2010 Some rights reserved: Creative Commons Attribution-Noncommercial-Share Alike http://creativecommons.org/licenses/by-nc-sa/3.0/
  • 2.
  • 3.
    Thread Thread StackCode Heap Stack
  • 4.
  • 5.
    Race Conditions publicclass BankAccount { private int balance; public void adjustBalance(int amount) { balance = balance + amount; } ... }
  • 6.
    Memory Consistency (A)Initially Thread B Instructions may be re-ordered a = true; b = true; return !b | a; boolean a = false; boolean b = false; Thread A Possible for Thread B to see b as true before a is true.
  • 7.
    Memory Consistency (B)Initially Thread B Partially constructed objects can be visible object = new MyClass(); if (object != null) object.doSomething(); MyClass object = null; Thread A object may not be in a consistent state in thread B
  • 8.
    If Possible: AvoidConcurrency!!
  • 9.
  • 10.
    Threads (in Java)Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); interface Runnable { void run(); } Looks strangely like the command pattern (covered last month). The Java ExecutorService interface is even more like the Command Pattern.
  • 11.
  • 12.
    Mutexes can fixrace conditions public class BankAccount { Object lock = new Object(); int balance; public void adjustBalance(int amount) { synchronize(lock) { balance = balance + amount; } }
  • 13.
    Mutexes can fixMemory Consistency Initially Thread B synchronize(lock) { a = true; b = true; } synchronize(lock) { return !b | a; } Object lock = new Object(); boolean a = false; boolean b = false; Thread A Must use the same lock! Can also fix some memory consistency problems using the volatile keyword.
  • 14.
    If you needclever analysis to show thread safety, then it is either broken now, or will be broken by some future maintainer!!!!
  • 15.
    Other Concurrency AbstractionsCondition Variables Semaphores. Latches. Barriers. Futures. Read/Write Locks. Blocking Queues. Exchangers. Threadpools. Atomic Compare-And-Set
  • 16.
  • 17.
    Fully Synchronized ObjectsPhoto by Kevin Hamm. Some rights reserved. See: http://www.flickr.com/photos/krhamm/171302278/in/set-72157594171880205/
  • 18.
    Fully Synchronized ObjectAll methods on a fully synchronized object are synchronized on a single lock.
  • 19.
    Resource Ordering Imageby Benjamin D. Esham for the Wikimedia Commons. Some rights reserved. See: http://en.wikipedia.org/wiki/File:Dining_philosophers.png/
  • 20.
  • 21.
    Passing immutable objectsas messages between threads. Concurrent modification ceases to be a problem!
  • 22.
  • 23.
    Double Check LockingUsed for lazy initialization Photo by Kirainet. Some rights reserved. See: http://www.flickr.com/photos/torek/2467519466/
  • 24.
    Double Check LockingEasy to stuff up!!!
  • 25.
    Double Check LockingWas not possible in Java before 1.5. Locks have become cheap, and so double-check not so useful. Usually better to use static initialization anyway. Was unreliable in C++/Posix threads when I last looked. Find out if it works in your language/platform before using!!
  • 26.
    Double Check LockingBut it is a nice demonstration of some concurrency issues
  • 27.
    Double check locking(Warning: did not work before Java 1.5) volatile Properties properties = null; final Object lock = new Object(); public Properties getProperties() { if (properties == null) { synchronized (lock) { if (properties == null) { tmp = new Properties(); tmp.load(inputStream); properties = tmp; } } } return properties; } Possibly broken! Definitely Brittle!
  • 28.
  • 29.
    Lock Free QueueQueue Dummy Node Real Head Node Tail Penultimate node Head Tail : Might point to last or second last node! References are all updated using the Atomic Test-And-Set.
  • 30.
    References M. Ben-Ari, Principles of Concurrent Programming, Prentice Hall. Doug Lea, Concurrent Programming in Java Second Edition. Design Principles and Patterns , Addison-Wesley. Brian Goetz, Java Concurrency in Practice . Pearson Education. Software Engineering Radio, Episodes 12, 19, and 29. http://www.se-radio.net/

Editor's Notes

  • #3 Processes and threads. Multiple cpu’s. IO. Responsiveness.
  • #7 Can be re-ordered by compiler, JVM, or caching effects.