from smile to tears: emotional stampedlock wjax... · from smile to tears: emotional stampedlock d...

75
From Smile to Tears: Emotional StampedLock © 2013 Heinz Kabutz – All Rights Reserved 1 From Smile To Tears: Emotional StampedLock Dr Heinz M. Kabutz Last updated 2013-11-05

Upload: others

Post on 10-Oct-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

1

From Smile To Tears: Emotional StampedLock

Dr Heinz M. Kabutz Last updated 2013-11-05

Page 2: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Heinz Kabutz Author of The Java Specialists' Newsletter

– Articles about advanced core Java programming

http://www.javaspecialists.eu

2

Page 3: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Why Synchronizers?

3

Page 4: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Why Synchronizers? Synchronizers keep shared mutable state

consistent– Don't need if we can make state immutable or unshared

Some applications need large amounts of state– Immutable could stress the garbage collector– Unshared could stress the memory volume

4

Page 5: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Coarse Grained Locking Overly coarse-grained locking means the CPUs are

starved for work– Only one core is busy at a time

Took 51 seconds to complete

5

Page 6: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

"Good" And "Bad" Context Switches "Good" Context Switch

– Thread has used up its time quantum and can be swapped out by the OS in a single clock cycle

– Also called "Involuntary" context switch

"Bad" Context Switch– Executing thread needs to stop because it cannot acquire

a resource held by another suspended thread– Also called "Voluntary" context switch– Can cost tens of thousands of clock cycles

6

Page 7: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Fine Grained Locking "Synchronized" causes "bad" context switches

– Thread cannot get the lock, so it is parked• Gives up its allocated time quantum

Took 745 seconds to complete

It appears that system time is 50% of the total time– So should this not have taken the same elapsed time as

before?

7

Page 8: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Independent Tasks With No Locking Instead of shared mutable state, every thread uses

only local data and in the end we merge the results

Took 28 seconds to complete with 100% utilization

8

Page 9: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Nonblocking Lock-free Algorithms Lock-based algorithms can cause scalability issues

– If a thread is holding a lock and is swapped out, no one can progress

– Amdahl's and Little's laws explain why we can't scale

Definitions of types of algorithms– Nonblocking: failure or suspension of one thread, cannot

cause another thread to fail or be suspended– Lock-free: at each step, some thread can make progress

9

Page 10: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

StampedLock

10

Page 11: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Motivation For StampedLock Some constructs need a form of read/write lock

ReentrantReadWriteLock can cause starvation– Plus it always uses pessimistic locking

11

Page 12: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Motivation For StampedLock StampedLock provides optimistic locking on reads

– Which can be converted easily to a pessimistic read

Write locks are always pessimistic– Also called exclusive locks

StampedLock is not reentrant

12

Page 13: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Read-Write Locks Refresher ReadWriteLock interface

– The writeLock() is exclusive - only one thread at a time– The readLock() is given to lots of threads at the same time

• Much better when mostly reads are happening– Both locks are pessimistic

13

Page 14: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Account With ReentrantReadWriteLockpublic class BankAccountWithReadWriteLock { private final ReadWriteLock lock = new ReentrantReadWriteLock(); private double balance; public void deposit(double amount) { lock.writeLock().lock(); try { balance = balance + amount; } finally { lock.writeLock().unlock(); } } public double getBalance() { lock.readLock().lock(); try { return balance; } finally { lock.readLock().unlock(); } }}

14

The cost overhead of the RWLock

means we need at least 2000

instructions to benefit from the

readLock() added throughput

Page 15: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

ReentrantReadWriteLock Starvation When readers are given priority, then writers might

never be able to complete (Java 5)

But when writers are given priority, readers might be starved (Java 6)

http://www.javaspecialists.eu/archive/Issue165.html

15

Page 16: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Java 5 ReadWriteLock Starvation We first acquire some read locks

We then acquire one write lock

Despite write lock waiting, readlocks are still issued

If enough read locks are issued,write lock will never get a chanceand the thread will be starved!

16

Page 17: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

ReadWriteLock In Java 6 Java 6 changed the policy

and now read locks have towait until the write lock hasbeen issued

However, now the readerscan be starved if we havea lot of writers

17

Page 18: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Synchronized vs ReentrantLock ReentrantReadWriteLock, ReentrantLock and

synchronized locks have the same memory semantics

However, synchronized is easier to write correctlysynchronized(this) { // do operation}

rwlock.writeLock().lock();try { // do operation} finally { rwlock.writeLock().unlock();}

18

Page 19: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Bad Try-Finally Blocks Either no try-finally at all

rwlock.writeLock().lock();// do operationrwlock.writeLock().unlock();

19

Page 20: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Bad Try-Finally Blocks Or the lock is locked inside the try block

try { rwlock.writeLock().lock(); // do operation} finally { rwlock.writeLock().unlock();}

20

Page 21: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Bad Try-Finally Blocks Or the unlock() call is forgotten in some places

altogether!

rwlock.writeLock().lock();// do operation// no unlock()

21

Page 22: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Introducing StampedLock Pros

– Has better performance than ReentrantReadWriteLock– Latest versions do not suffer from starvation of writers

Cons– Idioms are more difficult than with ReadWriteLock

• A small change in idiom code can make a big difference in performance

– Not nonblocking– Non-reentrant

22

Page 23: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Pessimistic Exclusive Locks (write)public class StampedLock { long writeLock() long writeLockInterruptibly() throws InterruptedException

long tryWriteLock() long tryWriteLock(long time, TimeUnit unit) throws InterruptedException

void unlockWrite(long stamp) boolean tryUnlockWrite()

Lock asWriteLock() long tryConvertToWriteLock(long stamp)

23

Page 24: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Pessimistic Non-Exclusive (read)public class StampedLock { (continued …) long readLock() long readLockInterruptibly() throws InterruptedException

long tryReadLock() long tryReadLock(long time, TimeUnit unit) throws InterruptedException

void unlockRead(long stamp) boolean tryUnlockRead()

Lock asReadLock() long tryConvertToReadLock(long stamp)

24

Optimistic reads to come ...

Page 25: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Bank Account With StampedLockpublic class BankAccountWithStampedLock { private final StampedLock lock = new StampedLock(); private double balance; public void deposit(double amount) { long stamp = lock.writeLock(); try { balance = balance + amount; } finally { lock.unlockWrite(stamp); } } public double getBalance() { long stamp = lock.readLock(); try { return balance; } finally { lock.unlockRead(stamp); } }}

25

The StampedLock reading is a typically cheaper than ReentrantReadWriteLock

Page 26: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Why Not Use Volatile?public class BankAccountWithVolatile { private volatile double balance;

public synchronized void deposit(double amount) { balance = balance + amount; }

public double getBalance() { return balance; }}

26

Much easier!Works because there

are no invariants across the fields.

Page 27: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Example With Invariants Across Fields Point class has x,y coordinates, "belong together"public class MyPoint { private double x, y; private final StampedLock sl = new StampedLock();

// method is modifying x and y, needs exclusive lock public void move(double deltaX, double deltaY) { long stamp = sl.writeLock(); try { x += deltaX; y += deltaY; } finally { sl.unlockWrite(stamp); } }

27

Page 28: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Optimistic Non-Exclusive "Locks"public class StampedLock { long tryOptimisticRead()

boolean validate(long stamp)

long tryConvertToOptimisticRead(long stamp)

28

Try to get an optimistic read lock - might return zero if an exclusive lock is active

checks whether a write lock was issued after the tryOptimisticRead() was called

Note: sequence validation requires stricter ordering than apply to normal volatile reads - a new explicit loadFence() was added

Page 29: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

29

Page 30: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

30

We get a stamp to use

for the optimistic

read

Page 31: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

31

We read field values into local

fields

Page 32: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

32

Next we validate that no write

locks have been issued in the meanwhile

Page 33: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

33

If they have, then we don't

know if our state is clean

Thus we acquire a pessimistic read lock and read the

state into local fields

Page 34: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Optimistic Readpublic double optimisticRead() { long stamp = sl.tryOptimisticRead(); double currentState1 = state1, currentState2 = state2, ... etc.; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentState1 = state1; currentState2 = state2, ... etc.; } finally { sl.unlockRead(stamp); } } return calculateSomething(state1, state2);}

34

Page 35: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Optimistic Read In Point Classpublic double distanceFromOrigin() { long stamp = sl.tryOptimisticRead(); double currentX = x, currentY = y; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentX = x; currentY = y; } finally { sl.unlockRead(stamp); } } return Math.hypot(currentX, currentY);}

35

Shorter code path in optimistic read leads

to better read performance than with original examples in

JavaDoc

Page 36: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

36

Page 37: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

37

We get a pessimistic read lock

Page 38: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

38

If the state is not the expected state, we

unlock and exit method

Note: the general unlock() method can unlock both

read and write locks

Page 39: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

39

We try convert our read lock to a write lock

Page 40: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

40

If we are able to upgrade to a write lock (ws != 0L), we

change the state and exit

Page 41: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

41

Else, we explicitly unlock the read lock and lock the write lock

And we try again

Page 42: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

42

If the state is not the expected state, we

unlock and exit method

This could happen if between the unlockRead() and the writeLock() another thread changed the values

Page 43: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

43

Because we hold the write lock, the tryConvertToWriteLock()

method will succeed

We update the state and exit

Page 44: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Code Idiom For Conditional Changepublic boolean changeStateIfEquals(oldState1, oldState2, ... newState1, newState2, ...) { long stamp = sl.readLock(); try { while (state1 == oldState1 && state2 == oldState2 ...) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; state1 = newState1; state2 = newState2; ... return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

44

Page 45: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Applying To Our Point Classpublic boolean moveIfAt(double oldX, double oldY, double newX, double newY) { long stamp = sl.readLock(); try { while (x == oldX && y == oldY) { long writeStamp = sl.tryConvertToWriteLock(stamp); if (writeStamp != 0L) { stamp = writeStamp; x = newX; y = newY; return true; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } return false; } finally { sl.unlock(stamp); }}

45

Page 46: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Performance StampedLock & RWLock We researched ReentrantReadWriteLock in 2008

– Discovered serious starvation of writers (exclusive lock) in Java 5– And also some starvation of readers in Java 6– http://www.javaspecialists.eu/archive/Issue165.html

StampedLock released to concurrency-interest list 12th Oct 2012– Worse writer starvation than in the ReentrantReadWriteLock– Missed signals could cause StampedLock to deadlock

Revision 1.35 released 28th Jan 2013– Changed to use an explicit call to loadFence()– Writers do not get starved anymore– Works correctly

46

Page 47: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Performance StampedLock & RWLock In our test, we used

– lambda-8-b75-linux-x64-28_jan_2013.tar.gz– Two CPUs, 4 Cores each, no hyperthreading

• 2x4x1– Ubuntu 9.10– 64-bit– Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz

• L1-Cache: 256KiB, internal write-through instruction• L2-Cache: 1MiB, internal write-through unified• L3-Cache: 8MiB, internal write-back unified

– JavaSpecialists.eu server• Never breaks a sweat delivering newsletters

47

Page 48: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Conversions To Pessimistic Reads In our experiment, reads had to be converted to

pessimistic reads less than 10% of the time– And in most cases, less than 1%

This means the optimistic read worked most of the time

48

Page 49: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

How Much Faster Is StampedLock Than ReentrantReadWriteLock? With a single thread

0

1

3

4

5

R=1,W=0 R=0,W=1

1.08x

0x 0x

4.43xx

fast

er th

an R

eadW

riteL

ock Read Speedup

Write Speedup

49

Page 50: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

With four threads

0

1

10

100

1000

R=4,W=0 R=3,W=1 R=2,W=2 R=1,W=3 R=0,W=4

1.2x1.1x1.2x

0.9x

353x

12x11x

64x

x fa

ster

than

Rea

dWrit

eLoc

k Read SpeedupWrite Speedup

50

How Much Faster Is StampedLock Than ReentrantReadWriteLock?

Page 51: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

With sixteen threadsThis demonstrates the

starvation problem on readers in RWLock

1

10

100

1000

10000

R=16,W=0 R=13,W=3 R=10,W=6 R=7,W=9 R=4,W=12 R=1,W=15

x fa

ster

than

Rea

dWrit

eLoc

k

Read SpeedupWrite Speedup

51

How Much Faster Is StampedLock Than ReentrantReadWriteLock?

Page 52: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Reader Throughput With StampedLock

100

1000

10000

1 2 4 8 16

Thro

ughp

ut (L

ogar

ithm

ic S

cale

)

Number of Reader Threads (no Writers)

Read ThroughputExpected (linear to n cores)

52

Page 53: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Writer Throughput With StampedLock

0

0.5

1.0

1.5

2.0

1 2 4 8 16

Thro

ughp

ut (L

inea

r Sca

le)

Number of Writer Threads (no Readers)

Write Throughput

Note: Linear Scale

throughput

53

Page 54: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Mixed Reader Throughput StampedLock

1

10

100

1000

10000

16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

Thro

ughp

ut (L

ogar

ithm

ic S

cale

)

Number of Reader Threads (16 - n Writers)

Read Throughput

54

Page 55: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Mixed Reader Throughput RWLock

Shows Reader

Starvation in

RWLock

0.001

0.01

0.1

1

10

100

16151413121110 9 8 7 6 5 4 3 2 1

ReentrantReadWriteLockTh

roug

hput

(Log

arith

mic

Sca

le)

Number of Reader Threads (16 - n Writers)

Read Throughput

55

Page 56: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Conclusion Of Performance Analysis StampedLock performed very well in all our tests

– Much faster than ReentrantReadWriteLock

Offers a way to do optimistic locking in Java

Good idioms have a big impact on the performance

56

Page 57: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Idioms With Lambdas

57

Page 58: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Idioms With Lambdas Java 8 lambdas allow us to define a structure of a

method, leaving the details of what to call over to users

– A bit like the "Template Method" Design Pattern

58

List<String> students = new ArrayList<>();Collections.addAll(students, "Anton", "Heinz", "John");students.forEach((s) -> System.out.println(s.toUpperCase()));

ANTONHEINZJOHN

Page 60: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Idioms For Using StampedLockimport java.util.concurrent.locks.*;import java.util.function.*;

public class LambdaStampedLock extends StampedLock { public void writeLock(Runnable writeJob) { long stamp = writeLock(); try { writeJob.run(); } finally { sl.unlockWrite(stamp); } }

60

lsl.writeLock( () -> { x += deltaX; y += deltaY; });

Page 61: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Idioms For Using StampedLockpublic Object optimisticRead(Supplier<?> supplier) { long stamp = tryOptimisticRead(); Object result = supplier.get(); if (!validate(stamp)) { stamp = readLock(); try { result = supplier.get(); } finally { unlockRead(stamp); } } return result;}

61

double[] xy = (double[])lsl.optimisticRead( () -> new double[]{x, y});return Math.hypot(xy[0], xy[1]);

Page 62: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Idioms For Using StampedLockpublic static boolean conditionalWrite( BooleanSupplier condition, Runnable action) { long stamp = readLock(); try { while (condition.getAsBoolean()) { long writeStamp = tryConvertToWriteLock(stamp); if (writeStamp != 0) { action.run(); stamp = writeStamp; return true; } else { unlockRead(stamp); stamp = writeLock(); } } return false; } finally { unlock(stamp); }}

62

return lsl.conditionalWrite( () -> x == oldX && y == oldY, () -> { x = newX; y = newY; });

Page 63: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Nonblocking Point

63

Page 64: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Nonblocking Point Instead of relying on synchronizers, use non-

blocking algorithm– Might create additional objects

• But a contended StampedLock will also create objects–

64

Page 65: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Store State Inside AtomicReferencepublic class PointNonblocking { public static final double[] INITIAL = new double[]{0, 0}; private final AtomicReference<double[]> xy = new AtomicReference<>(INITIAL);

public void move(double deltaX, double deltaY) { double[] current, next; do { current = xy.get(); double x = current[0]; double y = current[1]; next = new double[]{x + deltaX, y + deltaY}; } while (!xy.compareAndSet(current, next)); }

65

Page 66: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Reading Does Not Create Objects public double distanceFromOrigin() { double[] current = xy.get(); double x = current[0]; double y = current[1]; return Math.hypot(x, y); }

66

Page 67: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Conditional Write Can Make Objects public boolean moveIfAt(double oldX, double oldY, double newX, double newY) { double[] current, next; do { current = xy.get(); double x = current[0]; double y = current[1]; if (x != oldX || y != oldY) { return false; } next = new double[]{newX, newY}; } while (!xy.compareAndSet(current, next)); return true; }}

67

Page 68: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Which Is Fastest? StampedLock, synchronized or non-blocking?

– Depends on how you measure– For multiple readers, lock-free is probably faster

• http://mechanical-sympathy.blogspot.de/2013/08/lock-based-vs-lock-free-concurrent.html

– But synchronized might be faster thanboth in some cases

– Depends on how you use it• (Great consultant answer :-))

68

Page 69: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

69

Conclusion

Where to next?

Page 70: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

The Art Of Multiprocessor Programming Herlihy & Shavit

– Theoretical book on howthings work "under the hood"

– Good as background reading

16: Conclusion

70

Page 71: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

JSR 166 http://gee.cs.oswego.edu/

Concurrency-Interest mailing list– Usage patterns and bug reports on Phaser and

StampedLock are always welcome on the list

71

Page 72: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Mechanical Sympathy - Martin Thompson Mailing list

[email protected]

Blog– http://mechanical-sympathy.blogspot.com

72

Page 73: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

Heinz Kabutz ([email protected]) The Java Specialists' Newsletter

– Subscribe today:• http://www.javaspecialists.eu

Questions?

73

Page 74: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

74

From Smile To Tears: Emotional StampedLock

[email protected]

Questions?

Page 75: From Smile To Tears: Emotional StampedLock WJAX... · From Smile to Tears: Emotional StampedLock d Fine Grained Locking "Synchronized" causes "bad" context switches – Thread cannot

From Smile to Tears: Emotional StampedLock©

2013 Heinz K

abutz – All R

ights Reserved

75

The Java Specialists' Newsletter