• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Java Concurrency Idioms
 

Java Concurrency Idioms

on

  • 8,010 views

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

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

Statistics

Views

Total Views
8,010
Views on SlideShare
7,903
Embed Views
107

Actions

Likes
24
Downloads
395
Comments
0

5 Embeds 107

http://tech.puredanger.com 61
http://www.slideshare.net 40
http://192.168.6.52 4
http://us1.pazou.net 1
http://localhost 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Java Concurrency Idioms Java Concurrency Idioms Presentation Transcript

    • Java Concurrency Idioms Alex Miller
    • Sharing Signals Work
    • Sharing
    • Data Race! A
    • 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++; } }
    • volatile Is this safe? public class VolatileCounter implements Counter { private volatile int c = 0; public int increment() { return c++; } }
    • Synchronization A
    • synchronized public class SynchronizedCounter implements Counter { private int c = 0; public synchronized int increment() { return c++; } }
    • Atomic classes public class AtomicCounter implements Counter { private final AtomicInteger c = new AtomicInteger(0); public int increment() { return c.incrementAndGet(); } }
    • 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(); } } }
    • 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(); } } }
    • Encapsulation B A
    • Immutability A B
    • 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); } }
    • Thread Confinement A B
    • 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; } }
    • code.run()
    • 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
    • 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
    • Signals
    • Direct Thread Interaction join()
    • 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(); }
    • Wait / Notify notify() wait() A
    • wait() - wait() must occur in synchronization - should occur in loop on the wait condition synchronized(lock) { while(! someCondition) { lock.wait(); } }
    • notify() / notifyAll() - notify() / notifyAll() must occur in synchronization synchronized(lock) { lock.notifyAll(); }
    • Conditions signal() await() Condition
    • 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(); }
    • Condition signaling Lock lock = new ReentrantLock(); Condition condition = lock.newCondition(); // wait lock.lock(); try { condition.signalAll(); } finally { lock.unlock(); }
    • CyclicBarrier N: await() Cyclic Barrier(N)
    • 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();
    • CountDownLatch N: M: await() countDown() CountDown Latch(N)
    • CountDownLatch Threads wait for count to reach 0 int COUNT = 5; CountDownLatch latch = new CountDownLatch(COUNT); // count down latch.countDown(); // wait latch.await();
    • code.run()
    • Work
    • Thread Pools
    • Queues ...
    • ExecutorService
    • 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());
    • CompletionService
    • 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
    • code.run()
    • Questions? Sharing Signals Work
    • Blog: http://tech.puredanger.com Job: http://terracotta.org Twitter: http://twitter.com/puredanger All content © 2008 by Alex Miller Photos from iStockPhoto.com