SlideShare ist ein Scribd-Unternehmen logo
1 von 33
Non blocking programming
and waiting
Advanced non-blocking concurrency
Presented at GeekOut 2017
/Roman Elizarov @ JetBrains
Speaker: Roman Elizarov
•16+ years experience
•Previously developed high-perf
trading software @ Devexperts
•Teach concurrent & distributed
programming @ St. Petersburg
ITMO University
•Chief judge @ Northeastern
European Region of ACM ICPC
•Now work on Kotlin @ JetBrains
Why concurrency?
• Key motivators
• Performance
• Scalability
• Unless you need both, don’t
bother with concurrency:
• Write single-threaded
• Scale by running multiple copies of
code
Thread 1
Thread 2
Thread N
Shared
Object
Practical examples:
queue, cache,
dictionary, state,
statistics, log, etc
Share nothing and
sleep well
Basic concepts
Lock-freedom and waiting
What is blocking?
What is non-blocking algorithm?
Blocking (aka locking)
• Semi-formally
• In Java practice non-blocking algorithms
• just read/write volatile variable and/or use
• j.u.c.a.AtomicXXX classes with compareAndSet and other methods
• Blocking algorithms (with locks) use
• synchronized (…) which produces monitorEnter/monitorExit instrs
• j.u.c.l.Lock lock/unlock methods
• NOTE: You can code blocking without realizing it
An algorithm is called non-blocking (lock-free)
if suspension of any thread cannot
cause suspension of another thread
Toy problem solved with locks
Locks are the easiest way to
make your object linearizable
(aka thread-safe)
Just protect all operations on a
shared state with the same lock
(or monitor)
1
2
3
What is waiting [for condition]?
What is waiting operation?
sometimes aka “blocking”, too 
Waiting for condition
• Formally
• Waiting is orthogonal to blocking/non-blocking
• For example, let’s implement partial takeValue operation that is
defined only when there is value != null in DataHolder
Partial function
from object state set X to result set Y
is defined only on a subset of X’ of X.
Method invocation can complete only
when object state is in X’
(when condition is satisfied).
Waiting is easy with monitors
1
2
If in doubt, always use notifyAll instead of
notify (but can use notify here)
This is code with locks (synchronized):
suspension of one thread on any of these lines
causes suspension of all other threads that
attempt to do any operation
This is waiting code (partial function):
it is only defined when value != null
Non-blocking
Why and how
Why go non-blocking (aka lock-free)?
• Performance
• Locking is expensive when contended
• Actually, context switches are expensive
• Dead-lock avoidance
• Too much locking can get you into trouble
• Sometimes it is just easier to get rid of locks
Let’s go lock-free
1
2
3
4
Lock-free loop
expect update
Look ma, no locks!
Powerful we have become!
Lock-free waiting (aka parking)
2
3
4
1
“wait”
Lock-free wakeup (aka unparking)
• Note: in lock-free code order is important (first update, then unpark)
• Updaters are 100% wait-free (never locked out by other threads)
• Taker (takeValue) can get starved in CAS loop, but still non-blocking
(formally, lock-free)
“notify”
Park/unpark magic
LockSupport.unpark(T): “Makes available the
permit for the given thread, if it was not
already available. If the thread was blocked on
park then it will unblock. Otherwise, its next
call to park is guaranteed not to block.”
U update state unpark(T)
updateValue
T check state park()
takeValue
^ value == null
Lock-free waiting from multiple threads
• Must maintain wait queue of threads in a lock-free way
• This is a non-trivial
• j.u.c.l.AbstractQueuedSynchronizer is a good place to start
• It is used to implement a number of j.u.c.* classes:
- ReentrantLock
- ReentrantReadWriteLock
- Semaphore
- CountDownLatch
You can use it to for your own needs, too
Anatomy of AbstractQueuedSynchronizer
int state; // optionally use for state
wait queue <Node>; // nodes reference threads
int getState()
void setState(int newState)
boolean compareAndSetState(int expect, int update)
boolean tryAcquire(int arg)
boolean tryRelease(int arg)
int tryAcquireShared(int arg)
boolean tryReleaseShared(int arg)
void acquire(int arg)
void acquireInterruptibly(int arg)
boolean tryAcquireNanos(int arg, long nanos)
boolean release(int arg)
void acquireShared(int arg)
// and others
1
private state
2
state access
3
override
4
use
almost
separate
aspects
Anatomy of AbstractQueuedSynchronizer (2)
1
3
2
adds to
wait queue
4
unlinks from
wait queue
Our own synchronizer
1
2
3
Use synchronizer to implement notify/wait
1
2
3
Why double check? (more internals)
void doAcquireXXX(int arg) {
addToWaitQueue();
for (;;) {
if (isFirstInQueue() && tryAcquire(arg)) {
unlinkFromWaitQueue(); return;
}
doPark();
}
}
U update state release -> unparkSuccessor()
updateValue
T tryAcquire unlinkFromWaitQueue()
takeValue
^ valueRef.CAS(oldValue, null) == true
Simplified code
Naïve “performance improvement”
• The idea is to unpark just one thread when setting value for the first
time only (and avoid unparking on subsequent updates)
• IT FAILS SUBTLY(!).
1
2
T set release -> unparkSuccessor()
updateValue
U get park()
takeValue
^ valueRef.CAS(oldValue, null) == false
updateValue may cause concurrent tryAcquire to
fail on CAS and park, but we don’t call release in
this case anymore, so it will never unpark
.
Fail
CAS
^ oldValue != null1
2
3
Corrected Sync.tryAcquire method
• Use CAS-loop idiom to retry in the case of contention
• Optimal version in terms of context switching
1
2
Use the loop,
Luke!
This is optimal, but not fair!
• Let’s take a closer look at AQS.acquireXXX
• Thread might jump ahead of the queue
• Good or bad? – depends on the problem being solved
Make it fair (if needed)
Conclusion
• Waiting can be implemented in a non-blocking way
• Recap non-blocking: suspension of any thread (on any line of code) cannot
cause suspension of another thread
• Bonus: context switch only when really need to wait & wakeup
• Fairness: is an optional aspect of waiting
• AbstractQueuedSynchronizer
• is designed for writing custom lock-like classes
• but can be repurposed as a ready wait-queue impl for other cases
Lock-free programming is extremely
error-prone
Learn the patterns of concurrent code
You shall, young Padawan.
Thank you
Any questions?
Slides are available at www.slideshare.net/elizarov
email me to elizarov at gmail
relizarov

Weitere ähnliche Inhalte

Was ist angesagt?

Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924
yohanbeschi
 
Java bytecode and classes
Java bytecode and classesJava bytecode and classes
Java bytecode and classes
yoavwix
 
Ppl for students unit 4 and 5
Ppl for students unit 4 and 5Ppl for students unit 4 and 5
Ppl for students unit 4 and 5
Akshay Nagpurkar
 

Was ist angesagt? (20)

Implementing a JavaScript Engine
Implementing a JavaScript EngineImplementing a JavaScript Engine
Implementing a JavaScript Engine
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
 
Build, logging, and unit test tools
Build, logging, and unit test toolsBuild, logging, and unit test tools
Build, logging, and unit test tools
 
Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924Introduction to the Java bytecode - So@t - 20130924
Introduction to the Java bytecode - So@t - 20130924
 
Core java
Core javaCore java
Core java
 
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
Java Closures
Java ClosuresJava Closures
Java Closures
 
Java bytecode and classes
Java bytecode and classesJava bytecode and classes
Java bytecode and classes
 
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIsCS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
CS6270 Virtual Machines - Java Virtual Machine Architecture and APIs
 
Concurrency & Parallel Programming
Concurrency & Parallel ProgrammingConcurrency & Parallel Programming
Concurrency & Parallel Programming
 
Asynchronous I/O in Python 3
Asynchronous I/O in Python 3Asynchronous I/O in Python 3
Asynchronous I/O in Python 3
 
Java concurrency in practice
Java concurrency in practiceJava concurrency in practice
Java concurrency in practice
 
Automatic Reference Counting
Automatic Reference CountingAutomatic Reference Counting
Automatic Reference Counting
 
New Features Of JDK 7
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
 
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01
 
Ppl for students unit 4 and 5
Ppl for students unit 4 and 5Ppl for students unit 4 and 5
Ppl for students unit 4 and 5
 
Java memory model
Java memory modelJava memory model
Java memory model
 
camel-scala.pdf
camel-scala.pdfcamel-scala.pdf
camel-scala.pdf
 
Quick Introduction to Kotlin Coroutine for Android Dev
Quick Introduction to Kotlin Coroutine for Android DevQuick Introduction to Kotlin Coroutine for Android Dev
Quick Introduction to Kotlin Coroutine for Android Dev
 

Ähnlich wie Non blocking programming and waiting

Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
Daniel Blezek
 
AOS Lab 4: If you liked it, then you should have put a “lock” on it
AOS Lab 4: If you liked it, then you should have put a “lock” on itAOS Lab 4: If you liked it, then you should have put a “lock” on it
AOS Lab 4: If you liked it, then you should have put a “lock” on it
Zubair Nabi
 
Android webinar class_java_review
Android webinar class_java_reviewAndroid webinar class_java_review
Android webinar class_java_review
Edureka!
 

Ähnlich wie Non blocking programming and waiting (20)

Synchronization problem with threads
Synchronization problem with threadsSynchronization problem with threads
Synchronization problem with threads
 
Concurrency in Java
Concurrency in  JavaConcurrency in  Java
Concurrency in Java
 
Adv java unit 1 M.Sc CS.pdf
Adv java unit 1 M.Sc CS.pdfAdv java unit 1 M.Sc CS.pdf
Adv java unit 1 M.Sc CS.pdf
 
.NET Multithreading/Multitasking
.NET Multithreading/Multitasking.NET Multithreading/Multitasking
.NET Multithreading/Multitasking
 
Medical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUsMedical Image Processing Strategies for multi-core CPUs
Medical Image Processing Strategies for multi-core CPUs
 
Rethinking the debugger
Rethinking the debuggerRethinking the debugger
Rethinking the debugger
 
Groovy concurrency
Groovy concurrencyGroovy concurrency
Groovy concurrency
 
Need for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applicationsNeed for Async: Hot pursuit for scalable applications
Need for Async: Hot pursuit for scalable applications
 
Operating System lab
Operating System labOperating System lab
Operating System lab
 
Composable Futures with Akka 2.0
Composable Futures with Akka 2.0Composable Futures with Akka 2.0
Composable Futures with Akka 2.0
 
Let's Talk Locks!
Let's Talk Locks!Let's Talk Locks!
Let's Talk Locks!
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
 
Task parallel library presentation
Task parallel library presentationTask parallel library presentation
Task parallel library presentation
 
AOS Lab 4: If you liked it, then you should have put a “lock” on it
AOS Lab 4: If you liked it, then you should have put a “lock” on itAOS Lab 4: If you liked it, then you should have put a “lock” on it
AOS Lab 4: If you liked it, then you should have put a “lock” on it
 
Sync, async and multithreading
Sync, async and multithreadingSync, async and multithreading
Sync, async and multithreading
 
Storm Real Time Computation
Storm Real Time ComputationStorm Real Time Computation
Storm Real Time Computation
 
Android webinar class_java_review
Android webinar class_java_reviewAndroid webinar class_java_review
Android webinar class_java_review
 
The Nightmare of Locking, Blocking and Isolation Levels!
The Nightmare of Locking, Blocking and Isolation Levels!The Nightmare of Locking, Blocking and Isolation Levels!
The Nightmare of Locking, Blocking and Isolation Levels!
 
Java Thread
Java ThreadJava Thread
Java Thread
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCD
 

Mehr von Roman Elizarov

Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и Практика
Roman Elizarov
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)
Roman Elizarov
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Roman Elizarov
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
Roman Elizarov
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmer
Roman Elizarov
 

Mehr von Roman Elizarov (18)

Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018Kotlin Coroutines in Practice @ KotlinConf 2018
Kotlin Coroutines in Practice @ KotlinConf 2018
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017Fresh Async with Kotlin @ QConSF 2017
Fresh Async with Kotlin @ QConSF 2017
 
Scale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOneScale Up with Lock-Free Algorithms @ JavaOne
Scale Up with Lock-Free Algorithms @ JavaOne
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
 
Introduction to Kotlin coroutines
Introduction to Kotlin coroutinesIntroduction to Kotlin coroutines
Introduction to Kotlin coroutines
 
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2016 NEERC (Northeastern European Regional Contest) Problems Review
 
Многопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и ПрактикаМногопоточное Программирование - Теория и Практика
Многопоточное Программирование - Теория и Практика
 
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2015 NEERC (Northeastern European Regional Contest) Problems Review
 
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2014 NEERC (Northeastern European Regional Contest) Problems Review
 
Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)Многопоточные Алгоритмы (для BitByte 2014)
Многопоточные Алгоритмы (для BitByte 2014)
 
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
Теоретический минимум для понимания Java Memory Model (для JPoint 2014)
 
DIY Java Profiling
DIY Java ProfilingDIY Java Profiling
DIY Java Profiling
 
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2013 NEERC (Northeastern European Regional Contest) Problems Review
 
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems ReviewACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
ACM ICPC 2012 NEERC (Northeastern European Regional Contest) Problems Review
 
The theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmerThe theory of concurrent programming for a seasoned programmer
The theory of concurrent programming for a seasoned programmer
 
Пишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данныхПишем самый быстрый хеш для кэширования данных
Пишем самый быстрый хеш для кэширования данных
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 

Non blocking programming and waiting

  • 1. Non blocking programming and waiting Advanced non-blocking concurrency Presented at GeekOut 2017 /Roman Elizarov @ JetBrains
  • 2. Speaker: Roman Elizarov •16+ years experience •Previously developed high-perf trading software @ Devexperts •Teach concurrent & distributed programming @ St. Petersburg ITMO University •Chief judge @ Northeastern European Region of ACM ICPC •Now work on Kotlin @ JetBrains
  • 3. Why concurrency? • Key motivators • Performance • Scalability • Unless you need both, don’t bother with concurrency: • Write single-threaded • Scale by running multiple copies of code Thread 1 Thread 2 Thread N Shared Object Practical examples: queue, cache, dictionary, state, statistics, log, etc Share nothing and sleep well
  • 4.
  • 6. What is blocking? What is non-blocking algorithm?
  • 7. Blocking (aka locking) • Semi-formally • In Java practice non-blocking algorithms • just read/write volatile variable and/or use • j.u.c.a.AtomicXXX classes with compareAndSet and other methods • Blocking algorithms (with locks) use • synchronized (…) which produces monitorEnter/monitorExit instrs • j.u.c.l.Lock lock/unlock methods • NOTE: You can code blocking without realizing it An algorithm is called non-blocking (lock-free) if suspension of any thread cannot cause suspension of another thread
  • 8. Toy problem solved with locks Locks are the easiest way to make your object linearizable (aka thread-safe) Just protect all operations on a shared state with the same lock (or monitor) 1 2 3
  • 9. What is waiting [for condition]? What is waiting operation? sometimes aka “blocking”, too 
  • 10. Waiting for condition • Formally • Waiting is orthogonal to blocking/non-blocking • For example, let’s implement partial takeValue operation that is defined only when there is value != null in DataHolder Partial function from object state set X to result set Y is defined only on a subset of X’ of X. Method invocation can complete only when object state is in X’ (when condition is satisfied).
  • 11. Waiting is easy with monitors 1 2 If in doubt, always use notifyAll instead of notify (but can use notify here) This is code with locks (synchronized): suspension of one thread on any of these lines causes suspension of all other threads that attempt to do any operation This is waiting code (partial function): it is only defined when value != null
  • 13. Why go non-blocking (aka lock-free)? • Performance • Locking is expensive when contended • Actually, context switches are expensive • Dead-lock avoidance • Too much locking can get you into trouble • Sometimes it is just easier to get rid of locks
  • 14. Let’s go lock-free 1 2 3 4 Lock-free loop expect update Look ma, no locks!
  • 15. Powerful we have become!
  • 16. Lock-free waiting (aka parking) 2 3 4 1 “wait”
  • 17. Lock-free wakeup (aka unparking) • Note: in lock-free code order is important (first update, then unpark) • Updaters are 100% wait-free (never locked out by other threads) • Taker (takeValue) can get starved in CAS loop, but still non-blocking (formally, lock-free) “notify”
  • 18. Park/unpark magic LockSupport.unpark(T): “Makes available the permit for the given thread, if it was not already available. If the thread was blocked on park then it will unblock. Otherwise, its next call to park is guaranteed not to block.” U update state unpark(T) updateValue T check state park() takeValue ^ value == null
  • 19. Lock-free waiting from multiple threads • Must maintain wait queue of threads in a lock-free way • This is a non-trivial • j.u.c.l.AbstractQueuedSynchronizer is a good place to start • It is used to implement a number of j.u.c.* classes: - ReentrantLock - ReentrantReadWriteLock - Semaphore - CountDownLatch You can use it to for your own needs, too
  • 20. Anatomy of AbstractQueuedSynchronizer int state; // optionally use for state wait queue <Node>; // nodes reference threads int getState() void setState(int newState) boolean compareAndSetState(int expect, int update) boolean tryAcquire(int arg) boolean tryRelease(int arg) int tryAcquireShared(int arg) boolean tryReleaseShared(int arg) void acquire(int arg) void acquireInterruptibly(int arg) boolean tryAcquireNanos(int arg, long nanos) boolean release(int arg) void acquireShared(int arg) // and others 1 private state 2 state access 3 override 4 use almost separate aspects
  • 21. Anatomy of AbstractQueuedSynchronizer (2) 1 3 2 adds to wait queue 4 unlinks from wait queue
  • 23. Use synchronizer to implement notify/wait 1 2 3
  • 24. Why double check? (more internals) void doAcquireXXX(int arg) { addToWaitQueue(); for (;;) { if (isFirstInQueue() && tryAcquire(arg)) { unlinkFromWaitQueue(); return; } doPark(); } } U update state release -> unparkSuccessor() updateValue T tryAcquire unlinkFromWaitQueue() takeValue ^ valueRef.CAS(oldValue, null) == true Simplified code
  • 25. Naïve “performance improvement” • The idea is to unpark just one thread when setting value for the first time only (and avoid unparking on subsequent updates) • IT FAILS SUBTLY(!). 1 2
  • 26. T set release -> unparkSuccessor() updateValue U get park() takeValue ^ valueRef.CAS(oldValue, null) == false updateValue may cause concurrent tryAcquire to fail on CAS and park, but we don’t call release in this case anymore, so it will never unpark . Fail CAS ^ oldValue != null1 2 3
  • 27. Corrected Sync.tryAcquire method • Use CAS-loop idiom to retry in the case of contention • Optimal version in terms of context switching 1 2 Use the loop, Luke!
  • 28. This is optimal, but not fair! • Let’s take a closer look at AQS.acquireXXX • Thread might jump ahead of the queue • Good or bad? – depends on the problem being solved
  • 29. Make it fair (if needed)
  • 30. Conclusion • Waiting can be implemented in a non-blocking way • Recap non-blocking: suspension of any thread (on any line of code) cannot cause suspension of another thread • Bonus: context switch only when really need to wait & wakeup • Fairness: is an optional aspect of waiting • AbstractQueuedSynchronizer • is designed for writing custom lock-like classes • but can be repurposed as a ready wait-queue impl for other cases Lock-free programming is extremely error-prone
  • 31. Learn the patterns of concurrent code You shall, young Padawan.
  • 32.
  • 33. Thank you Any questions? Slides are available at www.slideshare.net/elizarov email me to elizarov at gmail relizarov