Concurrency Patterns


Published on

Talk on concurrency patterns given in March 2010 to the Melbourne Patterns Group

Published in: Technology, Education
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Processes and threads. Multiple cpu’s. IO. Responsiveness.
  • Can be re-ordered by compiler, JVM, or caching effects.
  • Concurrency Patterns

    1. 1. Concurrency Patterns David Kemp Melbourne Patterns Group March 2010 Some rights reserved: Creative Commons Attribution-Noncommercial-Share Alike
    2. 2. Concurrency: what and why?
    3. 3. Thread Thread Stack Code Heap Stack
    4. 4. Issues
    5. 5. Race Conditions public class BankAccount { private int balance; public void adjustBalance(int amount) { balance = balance + amount; } ... }
    6. 6. Memory Consistency (A) <ul><li>Initially </li></ul><ul><li>Thread B </li></ul>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. 7. Memory Consistency (B) <ul><li>Initially </li></ul><ul><li>Thread B </li></ul>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. 8. If Possible: Avoid Concurrency!!
    9. 9. Concurrency Primitives
    10. 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. 11. Mutex (Mutual Exclusion Lock)
    12. 12. Mutexes can fix race conditions public class BankAccount { Object lock = new Object(); int balance; public void adjustBalance(int amount) { synchronize(lock) { balance = balance + amount; } }
    13. 13. Mutexes can fix Memory Consistency <ul><li>Initially </li></ul><ul><li>Thread B </li></ul>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. 14. If you need clever analysis to show thread safety, then it is either broken now, or will be broken by some future maintainer!!!!
    15. 15. Other Concurrency Abstractions <ul><li>Condition Variables </li></ul><ul><li>Semaphores. </li></ul><ul><li>Latches. </li></ul><ul><li>Barriers. </li></ul><ul><li>Futures. </li></ul><ul><li>Read/Write Locks. </li></ul><ul><li>Blocking Queues. </li></ul><ul><li>Exchangers. </li></ul><ul><li>Threadpools. </li></ul><ul><li>Atomic Compare-And-Set </li></ul>
    16. 16. Some Patterns
    17. 17. Fully Synchronized Objects Photo by Kevin Hamm. Some rights reserved. See:
    18. 18. Fully Synchronized Object All methods on a fully synchronized object are synchronized on a single lock.
    19. 19. Resource Ordering Image by Benjamin D. Esham for the Wikimedia Commons. Some rights reserved. See:
    20. 20. Copy-on-write
    21. 21. Passing immutable objects as messages between threads. <ul><li>Concurrent modification ceases to be a problem! </li></ul>
    22. 22. Partitioning
    23. 23. Double Check Locking <ul><li>Used for lazy initialization </li></ul>Photo by Kirainet. Some rights reserved. See:
    24. 24. Double Check Locking <ul><li>Easy to stuff up!!! </li></ul>
    25. 25. Double Check Locking <ul><li>Was not possible in Java before 1.5. </li></ul><ul><li>Locks have become cheap, and so double-check not so useful. </li></ul><ul><li>Usually better to use static initialization anyway. </li></ul><ul><li>Was unreliable in C++/Posix threads when I last looked. </li></ul><ul><li>Find out if it works in your language/platform before using!! </li></ul>
    26. 26. Double Check Locking <ul><li>But it is a nice demonstration of some concurrency issues </li></ul>
    27. 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. 28. Lock-free Queue
    29. 29. 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.
    30. 30. References <ul><li>M. Ben-Ari, Principles of Concurrent Programming, Prentice Hall. </li></ul><ul><li>Doug Lea, Concurrent Programming in Java Second Edition. Design Principles and Patterns , Addison-Wesley. </li></ul><ul><li>Brian Goetz, Java Concurrency in Practice . Pearson Education. </li></ul><ul><li>Software Engineering Radio, Episodes 12, 19, and 29. </li></ul>