Java Concurrency Idioms

6,863 views

Published on

An overview of Java concurrency idioms for managing shared data, coordinating multiple threads, and managing work.

Published in: Technology, Business
0 Comments
31 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,863
On SlideShare
0
From Embeds
0
Number of Embeds
114
Actions
Shares
0
Downloads
428
Comments
0
Likes
31
Embeds 0
No embeds

No notes for slide

Java Concurrency Idioms

  1. 1. Java Concurrency Idioms Alex Miller
  2. 2. Sharing Signals Work
  3. 3. Sharing
  4. 4. Data Race! A
  5. 5. Unsafe access NOT safe for multi-threaded access: public interface Counter { int increment(); } public class UnsafeCounter implements Counter { private int c = 0; public int increment() { return c++; } }
  6. 6. volatile Is this safe? public class VolatileCounter implements Counter { private volatile int c = 0; public int increment() { return c++; } }
  7. 7. Synchronization A
  8. 8. synchronized public class SynchronizedCounter implements Counter { private int c = 0; public synchronized int increment() { return c++; } }
  9. 9. Atomic classes public class AtomicCounter implements Counter { private final AtomicInteger c = new AtomicInteger(0); public int increment() { return c.incrementAndGet(); } }
  10. 10. ReentrantLock public class ReentrantLockCounter implements Counter { private final Lock lock = new ReentrantLock(); private int c = 0; public int increment() { lock.lock(); try { return c++; } finally { lock.unlock(); } } }
  11. 11. ReentrantReadWriteLock public class ReentrantRWLockCounter implements Counter { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private int c = 0; public int increment() { lock.writeLock().lock(); try { return c++; } finally { lock.writeLock().unlock(); } } public int read() { lock.readLock().lock(); try { return c; } finally { lock.readLock().unlock(); } } }
  12. 12. Encapsulation B A
  13. 13. Immutability A B
  14. 14. Immutability Make field final, “mutator” methods return new immutable instances. public class Speed { private final int milesPerHour; public Speed(int milesPerHour) { this.milesPerHour = milesPerHour; } public Speed sawCop() { return new Speed(this.milesPerHour - 10); } }
  15. 15. Thread Confinement A B
  16. 16. ThreadLocal ThreadLocal gives every Thread its own instance, so no shared state. public class ThreadLocalCounter implements Counter { private final ThreadLocal<Integer> count = new ThreadLocal<Integer>(); public ThreadLocalCounter() { count.set(Integer.valueOf(0)); } public int increment() { Integer c = count.get(); int next = c.intValue() + 1; count.set(Integer.valueOf(next)); return next; } }
  17. 17. code.run()
  18. 18. 2 threads, 10000 reps 3,000 2,250 Total time (ms) 1,500 750 0 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% Write % sychronized RL(false) RL(true) RRWL(false) RRWL(true) synchronizedMap Concurrent
  19. 19. 2 threads, 10000 reps 130.0 97.5 Total time (ms) 65.0 32.5 0 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% Write % sychronized RL(false) RRWL(false) synchronizedMap Concurrent
  20. 20. Signals
  21. 21. Direct Thread Interaction join()
  22. 22. join() join() waits for another Thread to exit - signaling by completion Thread[] threads = new Thread[THREADS]; // start threads doing stuff // wait for completion for(int i=0; i<THREADS; i++) { threads[i].join(); }
  23. 23. Wait / Notify notify() wait() A
  24. 24. wait() - wait() must occur in synchronization - should occur in loop on the wait condition synchronized(lock) { while(! someCondition) { lock.wait(); } }
  25. 25. notify() / notifyAll() - notify() / notifyAll() must occur in synchronization synchronized(lock) { lock.notifyAll(); }
  26. 26. Conditions signal() await() Condition
  27. 27. Condition waiting Same as wait/notify but more flexible Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); // wait lock.lock(); try { while(! theCondition) { condition.await(1, TimeUnit.SECONDS); } } finally { lock.unlock(); }
  28. 28. Condition signaling Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); // wait lock.lock(); try { condition.signalAll(); } finally { lock.unlock(); }
  29. 29. CyclicBarrier N: await() Cyclic Barrier(N)
  30. 30. CyclicBarrier Wait for known # of threads to reach barrier, then release. Can be used multiple times. int THREADS = 5; CyclicBarrier barrier = new CyclicBarrier(THREADS); // in thread, wait to start barrier.await(); // do stuff // in thread, wait to stop barrier.await();
  31. 31. CountDownLatch N: M: await() countDown() CountDown Latch(N)
  32. 32. CountDownLatch Threads wait for count to reach 0 int COUNT = 5; CountDownLatch latch = new CountDownLatch(COUNT); // count down latch.countDown(); // wait latch.await();
  33. 33. code.run()
  34. 34. Work
  35. 35. Thread Pools
  36. 36. Queues ...
  37. 37. ExecutorService
  38. 38. ExecutorService Executors has helper methods to create different kinds of ExecutorServices backed by thread pools // Create service backed by thread pool ExecutorService service = Executors.newFixedThreadPool(THREADS); // Define a Work that is Runnable class Work implements Runnable {...} // Submit work to the thread pool service.execute(new Work());
  39. 39. CompletionService
  40. 40. CompletionService CompletionService combines an ExecutorService with a completion queue. // Create completion service backed by thread pool ExecutorService executor = Executors.newFixedThreadPool(THREADS); CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executor); // Submit work completionService.submit( new Callable<Integer>() { .. } ); // Wait for a result to be available Future<Integer> result = completionService.take(); Integer value = result.get(); // blocks
  41. 41. code.run()
  42. 42. Questions? Sharing Signals Work
  43. 43. Blog: http://tech.puredanger.com Job: http://terracotta.org Twitter: http://twitter.com/puredanger All content © 2008 by Alex Miller Photos from iStockPhoto.com

×