SlideShare a Scribd company logo
1 of 26
Locks? We don’t need no
       stinkin’ Locks!

            @mikeb2701
http://bad-concurrency.blogspot.com
                                Image: http://subcirlce.co.uk
Memory Models
Happens-Before
Causality
Causality
  Fear will keep the
 local systems inline.
     instructions
           - Grand Moff Wilhuff Tarkin
•   Loads are not reordered with other loads.


•   Stores are not reordered with other stores.


•   Stores are not reordered with older loads.


•   In a multiprocessor system, memory ordering obeys causality (memory
    ordering respects transitive visibility).


•   In a multiprocessor system, stores to the same location have a total order.


•   In a multiprocessor system, locked instructions to the same
    location have a total order.


•   Loads and Stores are not reordered with locked instructions.
Non-Blocking
 Primitives
Unsafe
public class AtomicLong extends Number
                        implements Serializable {

    // ...
    private volatile long value;

    // ...
    /**
      * Sets to the given value.
      *
      * @param newValue the new value
      */
    public final void set(long newValue) {
         value = newValue;
    }

    // ...
}
# {method} 'set' '(J)V' in 'java/util/concurrent/atomic/AtomicLong'
# this:       rsi:rsi   = 'java/util/concurrent/atomic/AtomicLong'
# parm0:      rdx:rdx   = long
#             [sp+0x20] (sp of caller)
  mov    0x8(%rsi),%r10d
  shl    $0x3,%r10
  cmp    %r10,%rax
  jne    0x00007f1f410378a0 ;     {runtime_call}
  xchg   %ax,%ax
  nopl   0x0(%rax,%rax,1)
  xchg   %ax,%ax
  push   %rbp
  sub    $0x10,%rsp
  nop
  mov    %rdx,0x10(%rsi)
  lock addl $0x0,(%rsp)     ;*putfield value
                            ; - j.u.c.a.AtomicLong::set@2 (line 112)
  add    $0x10,%rsp
  pop    %rbp
  test   %eax,0xa40fd06(%rip)         # 0x00007f1f4b471000
                            ;   {poll_return}
public class AtomicLong extends Number
                        implements Serializable {


    // setup to use Unsafe.compareAndSwapLong for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    // ...
    /**
      * Eventually sets to the given value.
      *
      * @param newValue the new value
      * @since 1.6
      */
    public final void lazySet(long newValue) {
         unsafe.putOrderedLong(this, valueOffset, newValue);
    }

    // ...
}
# {method} 'lazySet' '(J)V' in 'java/util/concurrent/atomic/
AtomicLong'
# this:       rsi:rsi   = 'java/util/concurrent/atomic/AtomicLong'
# parm0:      rdx:rdx   = long
#             [sp+0x20] (sp of caller)
  mov    0x8(%rsi),%r10d
  shl    $0x3,%r10
  cmp    %r10,%rax
  jne    0x00007f1f410378a0 ;     {runtime_call}
  xchg   %ax,%ax
  nopl   0x0(%rax,%rax,1)
  xchg   %ax,%ax
  push   %rbp
  sub    $0x10,%rsp
  nop
  mov    %rdx,0x10(%rsi)     ;*invokevirtual putOrderedLong
                             ; - AtomicLong::lazySet@8 (line 122)
  add    $0x10,%rsp
  pop    %rbp
  test   %eax,0xa41204b(%rip)         # 0x00007f1f4b471000
                             ;   {poll_return}
public class AtomicInteger extends Number
                           implements Serializable {

    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    private volatile int value;

    //...

    public final boolean compareAndSet(int expect,
                                       int update) {
        return unsafe.compareAndSwapInt(this, valueOffset,
                                        expect, update);
    }
}
# {method} 'compareAndSet' '(JJ)Z' in 'java/util/concurrent/
atomic/AtomicLong'
  # this:       rsi:rsi    = 'java/util/concurrent/atomic/AtomicLong'
  # parm0:      rdx:rdx    = long
  # parm1:      rcx:rcx    = long
  #             [sp+0x20] (sp of caller)
  mov     0x8(%rsi),%r10d
  shl     $0x3,%r10
  cmp     %r10,%rax
  jne     0x00007f6699037a60 ;      {runtime_call}
  xchg    %ax,%ax
  nopl    0x0(%rax,%rax,1)
  xchg    %ax,%ax
  sub     $0x18,%rsp
  mov     %rbp,0x10(%rsp)
  mov     %rdx,%rax
  lock cmpxchg %rcx,0x10(%rsi)
  sete    %r11b
  movzbl %r11b,%r11d ;*invokevirtual compareAndSwapLong
                        ; - j.u.c.a.AtomicLong::compareAndSet@9 (line
149)
  mov     %r11d,%eax
  add     $0x10,%rsp
  pop     %rbp
  test    %eax,0x91df935(%rip)          # 0x00007f66a223e000
                        ;   {poll_return}
set()   compareAndSet      lazySet()
  9



6.75



 4.5



2.25



  0
                 nanoseconds/op
Example - Disruptor Multi-producer




private void publish(Disruptor disruptor, long value) {
    long next = disruptor.next();
    disruptor.setValue(next, value);
    disruptor.publish(next);
}
Example - Disruptor Multi-producer
public long next() {
    long next;
    long current;

    do {
        current = nextSequence.get();
        next = current + 1;
        while (next > (readSequence.get() + size)) {
            LockSupport.parkNanos(1L);
            continue;
        }
    } while (!nextSequence.compareAndSet(current, next));

    return next;
}
Algorithm: Spin - 1



public void publish(long sequence) {
    long sequenceMinusOne = sequence - 1;
    while (cursor.get() != sequenceMinusOne) {
        // Spin
    }

    cursor.lazySet(sequence);
}
Spin - 1
                    25



                  18.75
million ops/sec




                   12.5



                   6.25



                     0
                          1   2   3     4         5      6   7   8
                                      Producer Threads
Algorithm: Co-Op
public void publish(long sequence) {
    int counter = RETRIES;
    while (sequence - cursor.get() > pendingPublication.length()) {
        if (--counter == 0) {
            Thread.yield();
            counter = RETRIES;
        }
    }

    long expectedSequence = sequence - 1;
    pendingPublication.set((int) sequence & pendingMask, sequence);

    if (cursor.get() >= sequence) { return; }

    long nextSequence = sequence;
    while (cursor.compareAndSet(expectedSequence, nextSequence)) {
        expectedSequence = nextSequence;
        nextSequence++;
        if (pendingPublication.get((int) nextSequence & pendingMask) != nextSequence) {
            break;
        }
    }
}
Spin - 1              Co-Op
                   30



                  22.5
million ops/sec




                   15



                   7.5



                    0
                         1   2   3            4         5      6   7   8
                                            Producer Threads
Algorithm: Buffer
public long next() {
    long next;
    long current;

    do {
        current = cursor.get();
        next = current + 1;
        while (next > (readSequence.get() + size)) {
            LockSupport.parkNanos(1L);
            continue;
        }
    } while (!cursor.compareAndSet(current, next));

    return next;
}
Algorithm: Buffer


public void publish(long sequence) {
    int publishedValue = (int) (sequence >>> indexShift);
    published.set(indexOf(sequence), publishedValue);
}



// Get Value
int availableValue = (int) (current >>> indexShift);
int index = indexOf(current);
while (published.get(index) != availableValue) {
     // Spin
}
Spin - 1   Co-Op             Buffer
                   70



                  52.5
million ops/sec




                   35



                  17.5



                    0
                         1   2        3     4             5       6    7   8
                                                Threads
Stuff that sucks...
Q&A
• https://github.com/mikeb01/jax2012
• http://www.lmax.com/careers
• http://www.infoq.com/presentations/Lock-
  free-Algorithms
• http://www.youtube.com/watch?
  v=DCdGlxBbKU4

More Related Content

What's hot

JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
Charles Nutter
 
Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromq
Ruben Tan
 

What's hot (20)

JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Don’t block the event loop!
Don’t block the event loop!Don’t block the event loop!
Don’t block the event loop!
 
Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!Inside the JVM - Follow the white rabbit!
Inside the JVM - Follow the white rabbit!
 
Java concurrency in practice
Java concurrency in practiceJava concurrency in practice
Java concurrency in practice
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)
 
Learning Python from Data
Learning Python from DataLearning Python from Data
Learning Python from Data
 
NovaProva, a new generation unit test framework for C programs
NovaProva, a new generation unit test framework for C programsNovaProva, a new generation unit test framework for C programs
NovaProva, a new generation unit test framework for C programs
 
Introduction to Debuggers
Introduction to DebuggersIntroduction to Debuggers
Introduction to Debuggers
 
Async programming and python
Async programming and pythonAsync programming and python
Async programming and python
 
Javascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and GulpJavascript TDD with Jasmine, Karma, and Gulp
Javascript TDD with Jasmine, Karma, and Gulp
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programs
 
Kernel Recipes 2019 - Formal modeling made easy
Kernel Recipes 2019 - Formal modeling made easyKernel Recipes 2019 - Formal modeling made easy
Kernel Recipes 2019 - Formal modeling made easy
 
Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013Beyond JVM - YOW! Sydney 2013
Beyond JVM - YOW! Sydney 2013
 
The Simple Scheduler in Embedded System @ OSDC.TW 2014
The Simple Scheduler in Embedded System @ OSDC.TW 2014The Simple Scheduler in Embedded System @ OSDC.TW 2014
The Simple Scheduler in Embedded System @ OSDC.TW 2014
 
JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011JVM for Dummies - OSCON 2011
JVM for Dummies - OSCON 2011
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScript
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Distributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromqDistributed app development with nodejs and zeromq
Distributed app development with nodejs and zeromq
 
Global Interpreter Lock: Episode III - cat < /dev/zero > GIL;
Global Interpreter Lock: Episode III - cat < /dev/zero > GIL;Global Interpreter Lock: Episode III - cat < /dev/zero > GIL;
Global Interpreter Lock: Episode III - cat < /dev/zero > GIL;
 
不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)不深不淺,帶你認識 LLVM (Found LLVM in your life)
不深不淺,帶你認識 LLVM (Found LLVM in your life)
 

Viewers also liked

Viewers also liked (10)

Java 9 Functionality and Tooling
Java 9 Functionality and ToolingJava 9 Functionality and Tooling
Java 9 Functionality and Tooling
 
Live Demo from JavaOne
Live Demo from JavaOneLive Demo from JavaOne
Live Demo from JavaOne
 
2015 Java update and roadmap, JUG sevilla
2015  Java update and roadmap, JUG sevilla2015  Java update and roadmap, JUG sevilla
2015 Java update and roadmap, JUG sevilla
 
Career Advice for Programmers
Career Advice for Programmers Career Advice for Programmers
Career Advice for Programmers
 
Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)
 
Migrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from EclipseMigrating to IntelliJ IDEA from Eclipse
Migrating to IntelliJ IDEA from Eclipse
 
Becoming fully buzzword compliant
Becoming fully buzzword compliantBecoming fully buzzword compliant
Becoming fully buzzword compliant
 
Staying Ahead of the Curve
Staying Ahead of the CurveStaying Ahead of the Curve
Staying Ahead of the Curve
 
Staying Ahead of the Curve
Staying Ahead of the CurveStaying Ahead of the Curve
Staying Ahead of the Curve
 
Real World Java 9
Real World Java 9Real World Java 9
Real World Java 9
 

Similar to Lock? We don't need no stinkin' locks!

エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理
maruyama097
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
knight1128
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
Charles Nutter
 

Similar to Lock? We don't need no stinkin' locks! (20)

エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理
 
Java util concurrent
Java util concurrentJava util concurrent
Java util concurrent
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Alexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for DevelopersAlexander Reelsen - Seccomp for Developers
Alexander Reelsen - Seccomp for Developers
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기[245] presto 내부구조 파헤치기
[245] presto 내부구조 파헤치기
 
Clojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVMClojure: Practical functional approach on JVM
Clojure: Practical functional approach on JVM
 
bluespec talk
bluespec talkbluespec talk
bluespec talk
 
The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]RxJava applied [JavaDay Kyiv 2016]
RxJava applied [JavaDay Kyiv 2016]
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
C++ CoreHard Autumn 2018. Concurrency and Parallelism in C++17 and C++20/23 -...
 
Marat-Slides
Marat-SlidesMarat-Slides
Marat-Slides
 
3
33
3
 
Java Performance Puzzlers
Java Performance PuzzlersJava Performance Puzzlers
Java Performance Puzzlers
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
 
JavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for DummiesJavaOne 2012 - JVM JIT for Dummies
JavaOne 2012 - JVM JIT for Dummies
 

More from Michael Barker (7)

Value Types
Value TypesValue Types
Value Types
 
Stuff I Learned About Performance
Stuff I Learned About PerformanceStuff I Learned About Performance
Stuff I Learned About Performance
 
Test automation 3
Test automation 3Test automation 3
Test automation 3
 
Disruptor yow2013 v2
Disruptor yow2013 v2Disruptor yow2013 v2
Disruptor yow2013 v2
 
Concurrecy techdrop
Concurrecy techdropConcurrecy techdrop
Concurrecy techdrop
 
Beginners guide-concurrency
Beginners guide-concurrencyBeginners guide-concurrency
Beginners guide-concurrency
 
Disruptor tools in action
Disruptor   tools in actionDisruptor   tools in action
Disruptor tools in action
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Recently uploaded (20)

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
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...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024AXA XL - Insurer Innovation Award Americas 2024
AXA XL - Insurer Innovation Award Americas 2024
 
Ransomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].pdfRansomware_Q4_2023. The report. [EN].pdf
Ransomware_Q4_2023. The report. [EN].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
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Lock? We don't need no stinkin' locks!

  • 1. Locks? We don’t need no stinkin’ Locks! @mikeb2701 http://bad-concurrency.blogspot.com Image: http://subcirlce.co.uk
  • 2.
  • 5. Causality Causality Fear will keep the local systems inline. instructions - Grand Moff Wilhuff Tarkin
  • 6. Loads are not reordered with other loads. • Stores are not reordered with other stores. • Stores are not reordered with older loads. • In a multiprocessor system, memory ordering obeys causality (memory ordering respects transitive visibility). • In a multiprocessor system, stores to the same location have a total order. • In a multiprocessor system, locked instructions to the same location have a total order. • Loads and Stores are not reordered with locked instructions.
  • 9. public class AtomicLong extends Number implements Serializable { // ... private volatile long value; // ... /** * Sets to the given value. * * @param newValue the new value */ public final void set(long newValue) { value = newValue; } // ... }
  • 10. # {method} 'set' '(J)V' in 'java/util/concurrent/atomic/AtomicLong' # this: rsi:rsi = 'java/util/concurrent/atomic/AtomicLong' # parm0: rdx:rdx = long # [sp+0x20] (sp of caller) mov 0x8(%rsi),%r10d shl $0x3,%r10 cmp %r10,%rax jne 0x00007f1f410378a0 ; {runtime_call} xchg %ax,%ax nopl 0x0(%rax,%rax,1) xchg %ax,%ax push %rbp sub $0x10,%rsp nop mov %rdx,0x10(%rsi) lock addl $0x0,(%rsp) ;*putfield value ; - j.u.c.a.AtomicLong::set@2 (line 112) add $0x10,%rsp pop %rbp test %eax,0xa40fd06(%rip) # 0x00007f1f4b471000 ; {poll_return}
  • 11. public class AtomicLong extends Number implements Serializable { // setup to use Unsafe.compareAndSwapLong for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; // ... /** * Eventually sets to the given value. * * @param newValue the new value * @since 1.6 */ public final void lazySet(long newValue) { unsafe.putOrderedLong(this, valueOffset, newValue); } // ... }
  • 12. # {method} 'lazySet' '(J)V' in 'java/util/concurrent/atomic/ AtomicLong' # this: rsi:rsi = 'java/util/concurrent/atomic/AtomicLong' # parm0: rdx:rdx = long # [sp+0x20] (sp of caller) mov 0x8(%rsi),%r10d shl $0x3,%r10 cmp %r10,%rax jne 0x00007f1f410378a0 ; {runtime_call} xchg %ax,%ax nopl 0x0(%rax,%rax,1) xchg %ax,%ax push %rbp sub $0x10,%rsp nop mov %rdx,0x10(%rsi) ;*invokevirtual putOrderedLong ; - AtomicLong::lazySet@8 (line 122) add $0x10,%rsp pop %rbp test %eax,0xa41204b(%rip) # 0x00007f1f4b471000 ; {poll_return}
  • 13. public class AtomicInteger extends Number implements Serializable { // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; private volatile int value; //... public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } }
  • 14. # {method} 'compareAndSet' '(JJ)Z' in 'java/util/concurrent/ atomic/AtomicLong' # this: rsi:rsi = 'java/util/concurrent/atomic/AtomicLong' # parm0: rdx:rdx = long # parm1: rcx:rcx = long # [sp+0x20] (sp of caller) mov 0x8(%rsi),%r10d shl $0x3,%r10 cmp %r10,%rax jne 0x00007f6699037a60 ; {runtime_call} xchg %ax,%ax nopl 0x0(%rax,%rax,1) xchg %ax,%ax sub $0x18,%rsp mov %rbp,0x10(%rsp) mov %rdx,%rax lock cmpxchg %rcx,0x10(%rsi) sete %r11b movzbl %r11b,%r11d ;*invokevirtual compareAndSwapLong ; - j.u.c.a.AtomicLong::compareAndSet@9 (line 149) mov %r11d,%eax add $0x10,%rsp pop %rbp test %eax,0x91df935(%rip) # 0x00007f66a223e000 ; {poll_return}
  • 15. set() compareAndSet lazySet() 9 6.75 4.5 2.25 0 nanoseconds/op
  • 16. Example - Disruptor Multi-producer private void publish(Disruptor disruptor, long value) { long next = disruptor.next(); disruptor.setValue(next, value); disruptor.publish(next); }
  • 17. Example - Disruptor Multi-producer public long next() { long next; long current; do { current = nextSequence.get(); next = current + 1; while (next > (readSequence.get() + size)) { LockSupport.parkNanos(1L); continue; } } while (!nextSequence.compareAndSet(current, next)); return next; }
  • 18. Algorithm: Spin - 1 public void publish(long sequence) { long sequenceMinusOne = sequence - 1; while (cursor.get() != sequenceMinusOne) { // Spin } cursor.lazySet(sequence); }
  • 19. Spin - 1 25 18.75 million ops/sec 12.5 6.25 0 1 2 3 4 5 6 7 8 Producer Threads
  • 20. Algorithm: Co-Op public void publish(long sequence) { int counter = RETRIES; while (sequence - cursor.get() > pendingPublication.length()) { if (--counter == 0) { Thread.yield(); counter = RETRIES; } } long expectedSequence = sequence - 1; pendingPublication.set((int) sequence & pendingMask, sequence); if (cursor.get() >= sequence) { return; } long nextSequence = sequence; while (cursor.compareAndSet(expectedSequence, nextSequence)) { expectedSequence = nextSequence; nextSequence++; if (pendingPublication.get((int) nextSequence & pendingMask) != nextSequence) { break; } } }
  • 21. Spin - 1 Co-Op 30 22.5 million ops/sec 15 7.5 0 1 2 3 4 5 6 7 8 Producer Threads
  • 22. Algorithm: Buffer public long next() { long next; long current; do { current = cursor.get(); next = current + 1; while (next > (readSequence.get() + size)) { LockSupport.parkNanos(1L); continue; } } while (!cursor.compareAndSet(current, next)); return next; }
  • 23. Algorithm: Buffer public void publish(long sequence) { int publishedValue = (int) (sequence >>> indexShift); published.set(indexOf(sequence), publishedValue); } // Get Value int availableValue = (int) (current >>> indexShift); int index = indexOf(current); while (published.get(index) != availableValue) { // Spin }
  • 24. Spin - 1 Co-Op Buffer 70 52.5 million ops/sec 35 17.5 0 1 2 3 4 5 6 7 8 Threads
  • 26. Q&A • https://github.com/mikeb01/jax2012 • http://www.lmax.com/careers • http://www.infoq.com/presentations/Lock- free-Algorithms • http://www.youtube.com/watch? v=DCdGlxBbKU4

Editor's Notes

  1. - Concurrency is taught all wrong.\n- What is non-blocking concurrency.\n- Mechanical Sympathy, locks/mutexs are a completely artificial construct\n- MTs concurrency course blocking v. non-blocking.\n- Tools for non-blocking concurrency functions of the CPU, need to look at CPU architecture first.\n
  2. - Causality\n- Why CPUs/Compilers reorder\n
  3. - Java Memory Model provides serial consistency for race-free programs\n- As-if-serial\n- Disallows out of thin air values\n- First main-stream programming language to include a memory model (C/C++ combination of the CPU and whatever the compiler happens to do.\n
  4. \n
  5. \n
  6. \n
  7. - volatile\n- java.util.concurrent.atomic.*\n - Atomic<Long|Integer|Reference>\n - Atomic<Long|Integer|Reference>Array (why use over an array of atomics)\n - Atomic<Long|Integer|Reference>FieldUpdater (can be a bit slow)\n
  8. - Fight club\n- If you’re smart enough\n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. - Thread wake ups\n- Hard spin\n- Spin with yield\n- PAUSE instruction - please add to Java\n- MONITOR and MWAIT\n
  26. \n