Java 8 - Stamped Lock

2,675 views

Published on

This talk was given in ilJUG on the 29th of July 2014 and discusses the new Java8 StampedLock class. It compares it to different locking mechanism is Java and shows some insights deduced from a simple benchmark

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,675
On SlideShare
0
From Embeds
0
Number of Embeds
35
Actions
Shares
0
Downloads
33
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Java 8 - Stamped Lock

  1. 1. ilJUG  Java  8  Launch  Event  #2   Stamped  Locks                                     ! Haim Yadid - Performize-IT
  2. 2. About  Me:  Haim  Yadid •21 Years of SW development experience •Performance Expert •Consulting R&D Groups •Training: Java Performance Optimization •Organizing : ILJUG
  3. 3. IL  JUG •Israeli Java User Group •Reborn at 1/14 •Meetup : http://www.meetup.com/IL-JUG •G+: https://plus.google.com/u/0/communities/110138558454900054301 •Twitter: @il_jug
  4. 4. Synchronization Synchronized keyword was introduced to the java language from the beginning Acquire the lock on any java object By default locking object instance on instance methods Locking the class on static methods © Copyright Performize IT LTD. synchronized void foo(){ do something(); } private Object x = new Object(); void bar() { synchronized (x) { do something; } }
  5. 5. Volatile keyword Insures access atomicity Visibility and order © Copyright Performize-IT LTD.CPU Profiling: Lock Contention private volatile long counter; public long getCounter() { return counter; } public void increment(long amount){ ++counter; }
  6. 6. Contention •Two threads are considered to be contended when they try to access same lock on the same time •Locking mechanism behaves differently under contention • Contention degrades performance dramatically
  7. 7. ReentrantLock Introduced in Java5 Part of the java.util.concurrent package Enhanced flexibility In Java 5 had better performance (fixed by now) © Copyright Performize IT LTD. private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } }
  8. 8. ReadWriteLock Introduced in Java5 Part of the java.util.concurrent package Two locks work together inside the same lock Any amount of readers can work concurrently Write locks are taken exclusively © Copyright Performize IT LTD. public void increment(long amount) { try { rwlock.writeLock().lock(); counter+=amount; } finally{ rwlock.writeLock().unlock(); } } public long getCounter() { try { rwlock.readLock().lock(); return counter; } finally { rwlock.readLock().unlock(); } }
  9. 9. Introduce Fairness Reentrant locks can work in fair and non fair mode. Fair mode means that requests to the lock object are accepted by the order they have been received. Prevents starvation Predictable latency Much slower © Copyright Performize IT LTD. private final ReentrantLock lock = new ReentrantLock(true);
  10. 10. Deadlocks A Deadlock is a severe problem in a Java program It is a non recoverable situation requires JVM restart A cycle of locks held by different thread where each one is waiting another thread to release a lock. © Copyright Performize-IT LTD.CPU Profiling: Concurrency problems Thread A Lock X Wait on Y Thread B Lock Y Wait on X
  11. 11. tryLock With synchronized keyword you are not able to control how much to wait Reetrantlock introduces tryLock() – If lock already taken return false tryLock(timeout,timeunit) – Waits for a certain amount of time Can be a solution to deadlocks © Copyright Performize-IT LTD.CPU Profiling: Lock Contention
  12. 12. CAS Other approaches use low level construct such as compare and swap Faster than synchronized Limited in functionality Can be used to develop complicated mechanism © Copyright Performize-IT LTD.CPU Profiling: Lock Contention private final AtomicLong atomic = new AtomicLong(); public void increment(long amount) { atomic.addAndGet(amount); } public long getCounter() { return atomic.get(); }
  13. 13. J8 - LongAdder Added to J8 - should be faster on multi threaded environment compared to AtomicLong Also a version for DoubleAdder © Copyright Performize-IT LTD.CPU Profiling: Lock Contention LongAdder adder = new LongAdder(); public void increment(long amount) { adder.add(amount); } public long getCounter() { return adder.longValue(); }
  14. 14. J8 - LongAdder Benchmark Taken from http://minddotout.wordpress.com/2013/05/11/ java-8-concurrency-longadder/ © Copyright Performize-IT LTD.CPU Profiling: Lock Contention
  15. 15. Stamped  Locks                                
  16. 16. Pessimistic Can work the same as read write lock Assumes contention Get a stamp from © Copyright Performize IT LTD. long stamp = rwlock.writeLock(); try { counter+= amount; } finally { rwlock.unlockWrite(stamp); } long stamp = rwlock.readLock(); try { result = counter; } finally { rwlock.unlockRead(stamp); } return result;
  17. 17. Optimistic Approach Optimistic Mechanism Try perform read if disturbed retry © Copyright Performize-IT LTD.CPU Profiling: Lock Contention private StampedLock rwlock = new StampedLock(); ! long stamp = rwlock.tryOptimisticRead(); result = counter; ! if (rwlock.validate(stamp)) { return result; }
  18. 18. Retry If failed one can retry © Copyright Performize-IT LTD.CPU Profiling: Lock Contention for (i=0;i<maxRetries;i++) { long stamp = rwlock.tryOptimisticRead(); result = counter; if (rwlock.validate(stamp)) { return result; } }
  19. 19. Micro Benchmark Original version developed by Tal Weiss (Takipi) https://github.com/takipi/counters-benchmark.git Modified benchmark here https://github.com/lifey/counters-benchmark.git The two benchmarks are very different and yield different results ( mine is better :) ) © Copyright Performize IT LTD.
  20. 20. Disclaimer Beware of micro benchmarks. Benchmarks can be flawed. Including this one Under different conditions they may behave differently They prove nothing for real life application Benchmark your real life applications as well Saying that benchmark contains: Warmup Average on 10 iterations after warmup © Copyright Performize IT LTD.
  21. 21. ReaderWriter A class which with configurable probability either increases a counter Reads its value A single iteration performs it for 200M times Number of threads is configurable © Copyright Performize IT LTD.
  22. 22. ReaderWriter © Copyright Performize IT LTD. if ((innerCounter % modulo) != 0) { // read
 long count = counter.getCounter();
 ! if (count > Main.TARGET_NUMBER) {
 Main.publish(System.currentTimeMillis());
 break;
 } } else { // write 
 counter.increment(modulo);
 }
 innerCounter++;
  23. 23. Different Implementations Volatile - using volatile keyword Atomic - AtomicLong Adder - LongAdder Synchronized Stamped (0,1,3,5 optimistic attempts) RW lock Fair RW lock © Copyright Performize IT LTD.
  24. 24. Results 1/2 writes - 1 thread © Copyright Performize IT LTD. 0 1750 3500 5250 7000 Volatile Atomic Adder Sync RWLock Stamped0 Stamped1 Stamped3 Stamped5
  25. 25. Results 1/2 writes © Copyright Performize IT LTD. ValueAxis 0 20000 40000 60000 80000 Volatile Atomic Adder Sync RWLock Stamped0 Stamped1 Stamped3 Stamped5 1 2 3 4
  26. 26. Results (1/10 writes) - single thread © Copyright Performize IT LTD. 0 2250 4500 6750 9000 Volatile Atomic Adder Sync RWLock Stamped0 Stamped1 Stamped3 Stamped5
  27. 27. Results (1/10 writes) © Copyright Performize IT LTD. 0 25000 50000 75000 100000 Volatile Atomic Adder Sync RWLock Stamped0 Stamped1 Stamped3 Stamped5
  28. 28. Results 1/100 writes © Copyright Performize IT LTD. 0 10000 20000 30000 40000 Volatile Atomic Adder Sync RWLock Stamped0 Stamped1 Stamped3 Stamped5
  29. 29. Results 1/100 writes © Copyright Performize IT LTD. 0 4000 8000 12000 16000 Volatile Atomic Adder Sync Stamped1 Stamped3 Stamped5
  30. 30. Insights RWlocks really suck under high contention. StampedLocks require at least one optimistic try. When update probability goes down more than one retry may be beneficial RWLock.tryLock is similar to lock Under low write rate StampedLock with retries can get close to atomic/volatile Fair locks are x100 slower than non fair locks under extreme cases © Copyright Performize IT LTD.
  31. 31. Additional Reading - LongAddr http://minddotout.wordpress.com/2013/05/11/ java-8-concurrency-longadder/ http://blog.palominolabs.com/2014/02/10/java-8- performance-improvements-longadder-vs- atomiclong/ http://psy-lob-saw.blogspot.co.il/2013/05/using-jmh- to-benchmark-multi-threaded.html?m=1 http://docs.oracle.com/javase/8/docs/api/java/util/ concurrent/atomic/LongAdder.html © Copyright Performize IT LTD.
  32. 32. Additional Reading - StampedLock http://docs.oracle.com/javase/8/docs/api/java/util/ concurrent/locks/StampedLock.html http://www.takipiblog.com/2014/05/30/java-8- stampedlocks-vs-readwritelocks-and-synchronized/ http://www.javaspecialists.eu/archive/Issue215.html © Copyright Performize IT LTD.
  33. 33. Thanks + Q&A + Contact Me © Copyright Performize-IT LTD. http://il.linkedin.com/in/haimyadid lifey@performize-it.com www.performize-it.com blog.performize-it.com https://github.com/lifey @lifeyx

×