Top Banner
Java Concurrency Idioms Alex Miller
43

Java Concurrency Idioms

May 20, 2015

Download

Technology

Alex Miller

An overview of Java concurrency idioms for managing shared data, coordinating multiple threads, and managing work.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Java Concurrency Idioms

Java Concurrency Idioms

Alex Miller

Page 2: Java Concurrency Idioms

Sharing

Signals

Work

Page 3: Java Concurrency Idioms

Sharing

Page 4: Java Concurrency Idioms

A

Data Race!

Page 5: Java Concurrency Idioms

Unsafe access

public interface Counter { int increment();}

public class UnsafeCounter implements Counter { private int c = 0;

public int increment() { return c++; }}

NOT safe for multi-threaded access:

Page 6: Java Concurrency Idioms

volatile

public class VolatileCounter implements Counter { private volatile int c = 0;

public int increment() { return c++; }}

Is this safe?

Page 7: Java Concurrency Idioms

A

Synchronization

Page 8: Java Concurrency Idioms

public class SynchronizedCounter implements Counter {

private int c = 0;

public synchronized int increment() { return c++; }}

synchronized

Page 9: Java Concurrency Idioms

public class AtomicCounter implements Counter { private final AtomicInteger c = new AtomicInteger(0);

public int increment() { return c.incrementAndGet(); }}

Atomic classes

Page 10: Java Concurrency Idioms

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(); } }}

ReentrantLock

Page 11: Java Concurrency Idioms

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(); } }}

ReentrantReadWriteLock

Page 12: Java Concurrency Idioms

B

A

Encapsulation

Page 13: Java Concurrency Idioms

A

B

Immutability

Page 14: Java Concurrency Idioms

public class Speed{ private final int milesPerHour; public Speed(int milesPerHour) { this.milesPerHour = milesPerHour; }

public Speed sawCop() { return new Speed(this.milesPerHour - 10); }}

ImmutabilityMake field final, “mutator” methods return new immutable instances.

Page 15: Java Concurrency Idioms

A

B

Thread Confinement

Page 16: Java Concurrency Idioms

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; }}

ThreadLocalThreadLocal gives every Thread its own instance, so no shared state.

Page 17: Java Concurrency Idioms

code.run()

Page 18: Java Concurrency Idioms

0

750

1,500

2,250

3,000

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%

2 threads, 10000 reps

Tota

l tim

e (m

s)

Write %

sychronized RL(false) RL(true)RRWL(false) RRWL(true) synchronizedMapConcurrent

Page 19: Java Concurrency Idioms

0

32.5

65.0

97.5

130.0

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%

2 threads, 10000 reps

Tota

l tim

e (m

s)

Write %

sychronized RL(false) RRWL(false)synchronizedMap Concurrent

Page 20: Java Concurrency Idioms

Signals

Page 21: Java Concurrency Idioms

join()

Direct Thread Interaction

Page 22: Java Concurrency Idioms

Thread[] threads = new Thread[THREADS];

// start threads doing stuff

// wait for completionfor(int i=0; i<THREADS; i++) { threads[i].join();}

join()join() waits for another Thread to exit - signaling by completion

Page 23: Java Concurrency Idioms

A

notify() wait()

Wait / Notify

Page 24: Java Concurrency Idioms

synchronized(lock) { while(! someCondition) { lock.wait(); }}

wait()- wait() must occur in synchronization- should occur in loop on the wait condition

Page 25: Java Concurrency Idioms

synchronized(lock) { lock.notifyAll();}

notify() / notifyAll()- notify() / notifyAll() must occur in synchronization

Page 26: Java Concurrency Idioms

Condition

signal() await()

Conditions

Page 27: Java Concurrency Idioms

Lock lock = new ReentrantLock();Condition condition = lock.newCondition();

// waitlock.lock();try { while(! theCondition) { condition.await(1, TimeUnit.SECONDS); }} finally { lock.unlock();}

Condition waitingSame as wait/notify but more flexible

Page 28: Java Concurrency Idioms

Lock lock = new ReentrantLock();Condition condition = lock.newCondition();

// waitlock.lock();try { condition.signalAll();} finally { lock.unlock();}

Condition signaling

Page 29: Java Concurrency Idioms

Cyclic

Barrier(N)

N:

await()

CyclicBarrier

Page 30: Java Concurrency Idioms

int THREADS = 5;CyclicBarrier barrier = new CyclicBarrier(THREADS);

// in thread, wait to startbarrier.await();

// do stuff

// in thread, wait to stopbarrier.await();

CyclicBarrierWait for known # of threads to reach barrier, then release. Can be used multiple times.

Page 31: Java Concurrency Idioms

CountDown

Latch(N)

countDown()await()

N: M:

CountDownLatch

Page 32: Java Concurrency Idioms

int COUNT = 5;CountDownLatch latch = new CountDownLatch(COUNT);

// count downlatch.countDown();

// waitlatch.await();

CountDownLatchThreads wait for count to reach 0

Page 33: Java Concurrency Idioms

code.run()

Page 34: Java Concurrency Idioms

Work

Page 35: Java Concurrency Idioms

Thread Pools

Page 36: Java Concurrency Idioms

. . .

Queues

Page 37: Java Concurrency Idioms

ExecutorService

Page 38: Java Concurrency Idioms

// Create service backed by thread poolExecutorService service = Executors.newFixedThreadPool(THREADS);

// Define a Work that is Runnableclass Work implements Runnable {...}

// Submit work to the thread poolservice.execute(new Work());

ExecutorServiceExecutors has helper methods to create different kinds of ExecutorServices backed by thread pools

Page 39: Java Concurrency Idioms

CompletionService

Page 40: Java Concurrency Idioms

CompletionService combines an ExecutorService with a completion queue.

// Create completion service backed by thread poolExecutorService executor = Executors.newFixedThreadPool(THREADS);CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executor);

// Submit workcompletionService.submit( new Callable<Integer>() { .. } );

// Wait for a result to be availableFuture<Integer> result = completionService.take();Integer value = result.get(); // blocks

CompletionService

Page 41: Java Concurrency Idioms

code.run()

Page 42: Java Concurrency Idioms

Sharing

Signals

Work

Questions?

Page 43: Java Concurrency Idioms

Blog: http://tech.puredanger.com

Job: http://terracotta.org

Twitter: http://twitter.com/puredanger

All content © 2008 by Alex MillerPhotos from iStockPhoto.com