[javaone 2011] models for concurrent programming

64
Models for Concurrent Programming Tobias Ivarsson hacker @ Neo Technology [email protected] twitter: @thobe web: http://thobe.org / http://neo4j.org /

Upload: tobias-lindaaker

Post on 12-May-2015

1.343 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: [JavaOne 2011] Models for Concurrent Programming

Models for Concurrent Programming

Tobias Ivarssonhacker @ Neo Technology

[email protected]: @thobeweb: http://thobe.org/ http://neo4j.org/

Page 2: [JavaOne 2011] Models for Concurrent Programming

Common misconceptions

2

Page 3: [JavaOne 2011] Models for Concurrent Programming

More threads==

More throughput

3

Page 4: [JavaOne 2011] Models for Concurrent Programming

Finite number of cores

4

Page 5: [JavaOne 2011] Models for Concurrent Programming

Other limiting factorsf.ex. I/O is only one pipe

5

Page 6: [JavaOne 2011] Models for Concurrent Programming

Locking always impedes performance

6

Page 7: [JavaOne 2011] Models for Concurrent Programming

7

Concurrency on the track, only

one in the station

Page 8: [JavaOne 2011] Models for Concurrent Programming

Amdahl’s law

8

Speedup ≤ 1

F +1-F

N

N: Number of processorsF: Serial fraction

Page 9: [JavaOne 2011] Models for Concurrent Programming

Throughput with synchronized

regions

9

Throughput: 3

Page 10: [JavaOne 2011] Models for Concurrent Programming

Throughput with synchronized

regions

9

wait...

Throughput: 6

Page 11: [JavaOne 2011] Models for Concurrent Programming

Throughput with synchronized

regions

9

wait...wait...

Throughput: 9

Page 12: [JavaOne 2011] Models for Concurrent Programming

Throughput with synchronized

regions

9

wait...wait...

wait...

Throughput: 11

Page 13: [JavaOne 2011] Models for Concurrent Programming

10

wait...wait...

wait...wait...

wait...wait...

wait...wait...

wait...

wait...wait...

Throughput: 11

Throughput with synchronized

regions

Page 14: [JavaOne 2011] Models for Concurrent Programming

11

wait...wait...

wait...wait...

wait...wait...

wait...

Throughput: 11

Throughput with synchronized

regions

Page 15: [JavaOne 2011] Models for Concurrent Programming

The fundamentals

12

๏Threads

๏Mutual exclusionsynchronization and locks

๏Java Memory Modelread/write barriers & publication

Page 16: [JavaOne 2011] Models for Concurrent Programming

The Java Memory ModelWhat you need to know

๏ Visibility / Publication of objects/fields

๏ (Un)Acceptable out-of-order behaviori.e. guarantees about ordering

๏ Implementations based on the hardware MM of the target platform

13

JSR 133

Page 17: [JavaOne 2011] Models for Concurrent Programming

Concurrency abstractions

14

Page 18: [JavaOne 2011] Models for Concurrent Programming

Java as we know it

15

Page 19: [JavaOne 2011] Models for Concurrent Programming

Threads

16

๏ Abstract the line of excution from the CPU(s)

๏ Provided by most (all mainstream) operating systems

๏ CPU execution can continue on another thread if one thread blocks

๏ Increases CPU utilization

Page 20: [JavaOne 2011] Models for Concurrent Programming

Monitors

17

synchronized (someMonitor){ // single threaded region}

read barrier

write barrier

Page 21: [JavaOne 2011] Models for Concurrent Programming

Volatile read/write

18

Page 22: [JavaOne 2011] Models for Concurrent Programming

19

class Thing { volatile String name; String getName() { return this.name; } void setName( String newName ) { this.name = newName; }}

read barrier

write barrier

๏Guarantees visibility:always read the latest value

๏Guarantees safe publication:no re-ordering ofpre-write ops withpost-write ops

Page 23: [JavaOne 2011] Models for Concurrent Programming

Monitors

20

synchronized (someMonitor){ // single threaded region}

read barrier

write barrier

๏Writes may not be reordered across the end

๏Reads may not be reordered across the start

Page 24: [JavaOne 2011] Models for Concurrent Programming

java.util.concurrent

21

Page 25: [JavaOne 2011] Models for Concurrent Programming

ConcurrentMap<String,Thing> map = new ConcurrentHashMap();

22

๏Adds atomic operations to the Map interface:- putIfAbsent(key, value)- remove(key, value)- replace(key,[oldVal,]newVal)- but not yet

putIfAbsent(key, #{makeValue()})

๏CHM is lock striped, i.e. synchronized on regions

Page 26: [JavaOne 2011] Models for Concurrent Programming

List<Thing> list = new CopyOnWriteArrayList();

23

๏Synchronize writers,unrestricted readers

๏Good for: #reads >> #writes

๏Readers get snapshot state:gives stable iteration

๏Volatile variable for immutable state to ensure publication

Page 27: [JavaOne 2011] Models for Concurrent Programming

public class CopyOnWriteArrayList<T>private volatile Object[] array = new Object[0];

public synchronized boolean add(T value) {Object[] newArray = Arrays.copyOf(array, array.length+1);newArray[array.length] = value;array = newArray; // write barrierreturn true;

} // write barrier

public Iterator<T> iterator() {return new ArrayIterator<T>(this.array); // read barrier

}

private static class ArrayIterator<T> implements Iterator<T> {// I’ve written too many of these to be amused any more ...

}24

Page 28: [JavaOne 2011] Models for Concurrent Programming

25

ExecutorService executor = new ThreadPoolExecutor();

executor.submit(new Runnable() { void run() { doWork(); }});

๏Focus on tasks - not threads

๏Mitigate thread start/stop overhead

๏Ensure a balanced number of threads for the target platform

Page 29: [JavaOne 2011] Models for Concurrent Programming

java.util.concurrent.locks

26

Page 30: [JavaOne 2011] Models for Concurrent Programming

27

LockSupport.park(); // currentThread

LockSupport.unpark(Thread t);

๏The thread will “sleep” until unparked

๏Although unpark-before-park marks the thread as unparked, returning from park immediately

๏... and there’s still the chance of spurious wakeups ...

๏Too low level for most people

Page 31: [JavaOne 2011] Models for Concurrent Programming

Lock lock = new ReentrantLock();

ReadWriteLock rwLock = new ReentrantReadWriteLock();

Lock read = rwLock.readLock();Lock write = rwLock.writeLock();

lock.lock();try { doWork() } finally { lock.unlock(); }

if ( lock.tryLock() )try { doWork() } finally { lock.unlock(); }

elsebackOffAndTryAgainLater();

28

// Two related locks

Page 32: [JavaOne 2011] Models for Concurrent Programming

java.util.concurrent.atomic

29

Page 33: [JavaOne 2011] Models for Concurrent Programming

30

AtomicReference<Thing> ref = new AtomicReference();

AtomicReferenceArray<Thing> array = new AtomicReferenceArray();

Page 34: [JavaOne 2011] Models for Concurrent Programming

30

AtomicReference<Thing> ref = new AtomicReference();

AtomicReferenceArray<Thing> array = new AtomicReferenceArray();

class MyAtomicThingReference { volatile Thing thing; static AtomicReferenceFieldUpdater

<MyAtomicThingReference,Thing> THING = newUpdater(...);

Thing swap( Thing newThing ) { return THING.getAndSet( this, newThing ); }}๏Atomic* gives you compareAndSet()

๏Atomic*Updater saves indirection:

๏One less object header - less memory

๏One read-address-get-object operation:better cache locality

Page 35: [JavaOne 2011] Models for Concurrent Programming

Java of Tomorrow(actually Today, JDK7 is already out)

31

Page 36: [JavaOne 2011] Models for Concurrent Programming

ForkJoin

32

๏More “advanced” Executor

๏Assumes/requires more of the tasks it runs

๏Tasks first split into multiple sub-tasks, push on stack

๏Idle workers “steal” work from the bottom of the stack of other workers

Page 37: [JavaOne 2011] Models for Concurrent Programming

Models not in Java today

33

Page 39: [JavaOne 2011] Models for Concurrent Programming

35

ParallelArray<Student> students = ...

double highestScore = students .filter( #{ Student s -> s.gradYear == 2010 } ) .map( #{ Student s -> s.score } ) .max();

Page 40: [JavaOne 2011] Models for Concurrent Programming

Transactional Memory

36

Page 41: [JavaOne 2011] Models for Concurrent Programming

37

void transfer( TransactionalLong source, TransactionalLong target, long amount ) {

try ( Transaction tx = txManager.beingTransaction() ) {

long sourceFunds = source.getValue(); if (sourceFunds < amount) { throw new InsufficientFundsException(); } source.setValue( sourceFunds - amount ); target.setValue( target.getValue() + amount );

tx.success(); }

}

Page 42: [JavaOne 2011] Models for Concurrent Programming

Actors

38

Page 43: [JavaOne 2011] Models for Concurrent Programming

39

class SimpleActor extends Actor { var state def receive = { case Get => self reply state case Set(newState) => state = newState }}

val response = simple !! Set( "new state" )Th

is m

eans

“s

end

mes

sage

Page 44: [JavaOne 2011] Models for Concurrent Programming

Scala Parallel Collection Framework

40

Page 45: [JavaOne 2011] Models for Concurrent Programming

Efficient Collection splitting & combining

41

Page 46: [JavaOne 2011] Models for Concurrent Programming

Efficient Collection splitting & combining

41

Page 47: [JavaOne 2011] Models for Concurrent Programming

Efficient Collection splitting & combining

41

Page 48: [JavaOne 2011] Models for Concurrent Programming

Efficient Collection splitting & combining

41

Page 49: [JavaOne 2011] Models for Concurrent Programming

Splittable maps

42

15

1745

82

Page 50: [JavaOne 2011] Models for Concurrent Programming

Splittable maps

43

8 5 15

2 174

Page 51: [JavaOne 2011] Models for Concurrent Programming

Hash tries

44

๏Similar performance to hash tables

๏Splittable (like arrays)

๏Memory (re)allocation more like trees

๏No resizing races

Page 52: [JavaOne 2011] Models for Concurrent Programming

Clojure

45

Page 53: [JavaOne 2011] Models for Concurrent Programming

Immutable by default

46

Page 54: [JavaOne 2011] Models for Concurrent Programming

Thread local(and scoped)

override

47

Page 55: [JavaOne 2011] Models for Concurrent Programming

48

(def x 10) ; create a root binding

(def x 42) ; redefine the root binding

(binding [x 13] ...) ; create a thread local override

Page 56: [JavaOne 2011] Models for Concurrent Programming

Transactional memory(ref) and (dosync ...)

49

Page 57: [JavaOne 2011] Models for Concurrent Programming

50

(def street (ref))(def city (ref))

(defn move [new-street new-city] (dosync ; synchronize the changes (ref-set street new-street) (ref-set city new-city))); will retry if txn fails due to concurrent change

(defn print-address [] (dosync ; get a snapshot state of the refs (printf "I live on %s in %s%n" @street @city)))

Page 58: [JavaOne 2011] Models for Concurrent Programming

(atom)easier API for AtomicReference

51

Page 59: [JavaOne 2011] Models for Concurrent Programming

52

(defstruct address-t :street :city)

(def address (atom))

(defn move [new-street new-city] (set address (struct address-t new-street new-city)))

(defn print-address [] (let [addr @address] ; get snapshot (printf "I live on %s in %s%n" (get addr :street) (get addr :city))))

Page 60: [JavaOne 2011] Models for Concurrent Programming

Explicit asynchronous updates

53

Page 61: [JavaOne 2011] Models for Concurrent Programming

(agent)A simpler cousin to actors

54

Page 62: [JavaOne 2011] Models for Concurrent Programming

55

(def account (agent))

(defn deposit [balance amount] (+ balance amount))

(send account deposit 1000)

Page 63: [JavaOne 2011] Models for Concurrent Programming

http://neotechnology.com

we’re hiringhttp://neotechnology.com/about-us/jobs

Page 64: [JavaOne 2011] Models for Concurrent Programming

Questions?