SlideShare a Scribd company logo
Java Memory Model
   The enigma of Java




       James Perry
About Me

Software Engineer at Barclays Capital
http://www.natureinspiredcode.com
http://github.com/natureinspired/8queen-ea
g-graphs
Twitter: @nature_inspired
JMM in a Nutshell

JMM is a universal contract for how threads
interact with memory in Java programs.
Happens-Before ordering: "official" reasoning
for thread interaction.
synchronized provides mutual exclusion and
memory visibility.
volatile provides atomic memory visibility.
public class SleepyThreadDemo {

    private static boolean awake;

    public static void main(String[] args) throws InterruptedException {
      Thread sleepyThread = new Thread(new Runnable() {
          public void run() {
            int zCount = 0;
            while(!awake) {
               zCount++;
            }
          }
      });
      sleepyThread.start();

        TimeUnit.SECONDS.sleep(1);
        awake = true;
    }

}
public class SleepyThreadDemo {

  private static boolean awake;

  public static void main(String[] args) throws InterruptedException {
    Thread sleepyThread = new Thread(new Runnable() {
        public void run() {
          int zCount = 0;
          if (!awake) {
              while(true) {
                zCount++;
              }
          }
        }
    });
    sleepyThread.start();

      TimeUnit.SECONDS.sleep(1);
      awake = true;
  }
Causality

    Cause
       Symmetric Multiprocessing (SMP)
       Memory Ordering
       Memory Barriers
       Compiler Optimisation
    Effect
       History
       Objectives
       Happens-Before Ordering
       Concurrency Constructs
Symmetrical Multiprocessing




          Memory Contention
          Cache Coherency
Symmetrical Multiprocessing
      T1       T2       Tn
Symmetrical Multiprocessing
     foo = 42        foo = 1        foo = 12




            public static int foo = 1
Symmetrical Multiprocessing
     foo = 42       foo = 42        foo = 42




            public static int foo = 42
Java Memory Model
Memory Ordering

                 1. CPU 0 executes a=1.
int a = 1;       2. CPU 0 looks “a” up in the cache, and finds
int b = a + 1;      that it is missing.
assert(b == 2)   3. CPU 0 therefore sends a “read invalidate” mes-
                    sage in order to get exclusive ownership of the
                    cache line containing “a”.
                 4. CPU 0 records the store to “a” in its store
                    buffer.
                 5. CPU 1 receives the “read invalidate” message,
                    and responds by transmitting the cache line
                    and removing that cacheline from its cache.
Memory Ordering
                 6. CPU 0 starts executing the b=a+1.
int a = 1;
                 7. CPU 0 receives the cache line from CPU 1,
int b = a + 1;   which still has a value of zero for “a”.
assert(b == 2)   8. CPU 0 loads “a” from its cache, finding the value
                 zero.
                 9. CPU 0 applies the entry from its store queue to
                 the newly arrived cache line, setting the value of “a”
                 in its cache to one.
                 10. CPU 0 adds one to the value zero loaded for
                 “a” above, and stores it into the cache line
                 containing “b” (which we will assume is already
                 owned by CPU 0).
                 11. CPU 0 executes assert(b==2), which fails.
Memory Ordering                1. CPU 0 executes a=1. The cache line
                                  is not in CPU 0’s cache, so CPU 0
                                  places the new value of “a” in its store
 @Singleton                       buffer and transmits a “read invalidate”
 class FooBar {                   message.
                               2. CPU 1 executes while(b==0)continue,
     private int a, b;            but the cache line containing “b” is not
                                  in its cache. It therefore transmits a
                                  “read” message.
     public void foo() {       3. CPU 0 executes b=1. It already owns
       a = 1;                     this cache line, so it stores the new
       b = 1;                     value of “b” in its cache line.
     }                         4. CPU 0 receives the “read” message,
                                  and transmits the cache line
     public void bar() {          containing the now-updated value of
       while(b==0) continue;      “b” to CPU 1, also marking the line as
       assert(a==1);              “shared” in its own cache.
     }

 }
Memory Ordering                5. CPU 1 receives the cache line
                               containing “b” and installs it in its cache.
                               6. CPU 1 can now finish executing while
                               (b==0) continue, and since it finds that
 @Singleton                    the value of “b” is 1, it proceeds to the
 class FooBar {                next statement.
                               7. CPU 1 executes the assert(a==1),
     private int a, b;         and, since CPU 1 is working with the old
                               value of “a”, this assertion fails.
     public void foo() {       8. CPU 1 receives the “read invalidate”
       a = 1;                  message, and transmits the cache line
                               containing “a” to CPU 0 and invalidates
       b = 1;
                               this cache line from its own cache. But it
     }                         is too late.
                               9. CPU 0 receives the cache line
     public void bar() {       containing “a” and applies the buffered
       while(b==0) continue;   store just in time to fall victim to CPU 1’s
       assert(a==1);           failed assertion.
     }

 }
1. CPU 0 executes a=1. The cache line is not in
Memory Ordering                   CPU 0’s cache, so CPU 0 places the new
                                  value of “a” in its store buffer and transmits a
                                  “read invalidate” message.
 @Singleton                    2. CPU 1 executes while(b==0)continue, but
 class FooBar {                   the cache line containing “b” is not in its
                                  cache. It therefore transmits a “read”
                                  message.
     private int a, b;         3. CPU 0 executes fence(), and marks all
                                  current store-buffer entries (namely, the
                                  a=1).
     public void foo() {       4. CPU 0 executes b=1. It already owns this
       a = 1;                     cache line, but there is a marked entry in the
       fence();                   store buffer. Therefore, rather than store the
                                  new value of “b” in the cache line, it instead
       b = 1;                     places it in the store buffer (but in an
     }                            unmarked entry).
                               5. CPU 0 receives the “read” message, and
                                  trans- mits the cache line containing the
     public void bar() {          original value of “b” to CPU 1. It also marks
       while(b==0) continue;      its own copy of this cache line as “shared”.
       assert(a==1);           6. CPU 1 receives the cache line containing “b”
                                  and installs it in its cache.
     }                         7. CPU 1 can now finish executing while(b==0)
                                  continue, but since it finds that the value of
 }                                'b' i still 0, it repeats the while statement. The
                                  new value of 'b' is safely hidden in CPU 0's
                                  store buffer.
Memory Fencing                 8. CPU 1 receives the “read invalidate”
                               message, and transmits the cache line
                               containing 'a' to CPU 0 and invalidates this
 @Singleton                    cache line from its own cache.
 class FooBar {                9. CPU 0 receives the cache line containing
                               'a' and applies the buffered store.
                               10. Since the store to 'a' was the only entry in
     private int a, b;         the store buffer that was marked by fence(),
                               CPU 0 can also store the new value 'b' -
                               expect for the fact that the cache line
     public void foo() {       containing 'b' is now in 'shared' state.
       a = 1;                  11. CPU 0 therefore sends an 'invalidate
       fence();                message to CPU 1'.
                               12. CPU 1 receives the 'invalidate' message,
       b = 1;                  invalidates the cache line containing 'b' from
     }                         its cache, and sends an 'acknowledgement'
                               message to CPU 0.
                               13. CPU 1 executes while(b==0)continue,
     public void bar() {       but the cache line containing 'b' is not in
       while(b==0) continue;   cache. It therefore transmits a 'read' message
       assert(a==1);           to CPU 0.
     }

 }
Memory Fencing                 14. CPU 0 receives the 'acknowledgement'
                               message, and puts the cache line containing 'b'
 @Singleton                    into the 'exclusive' state. CPU 0 now stores the
                               new value of 'b' into the cache line.
 class FooBar {                15. CPU 0 receives the 'read' message, and
                               transmits the cache line containing the original
     private int a, b;         value of 'b' to CPU 1. It also marks its own copy
                               of this cache as 'shared'.
                               16. CPU 1 receives the cache line containing 'b'
     public void foo() {       and installs it in its cache.
       a = 1;                  17. CPU 1 can now finish executing while
                               (b==0)continue and since it finds that the value
       fence();                of 'b' is 1, it proceeds to the next statement.
       b = 1;                  18. CPU 1 executes the assert(a==1) but the
     }                         cache line containing 'a' is no longer in its
                               cache. Once it gets this cache from CPU 0, it
                               will be working with the up-to-date value of 'a',
     public void bar() {       thus assertion passes.
       while(b==0) continue;
       assert(a==1);
     }

 }
Compiler Optimisations
Loop Fusion

int i = 0, size = 100;
int[] a = new int[size], b = new int[size];

for (i = 0; i < size; i++) {
   a[i] = 1;
}
for (i = 0; i < size; i++) {
   b[i] = 2;
}
Compiler Optimisations
Loop Fusion

int i = 0, size = 100;
int[] a = new int[size], b = new int[size];

for (i = 0; i < size; i++) {
   a[i] = 1;
   b[i] = 2;
}
Compiler Optimisations
Loop Fission

int i = 0, size = 100;
int[] a = new int[size], b = new int[size];

for (i = 0; i < size; i++) {
   a[i] = 1;
   b[i] = 2;
}
Compiler Optimisations
Loop Fission

int i = 0, size = 100;
int[] a = new int[size], b = new int[size];

for (i = 0; i < size; i++) {
   a[i] = 1;
}
for (i = 0; i < size; i++) {
   b[i] = 2;
}
Compiler Optimisations
Lock Coarsening

BigDecimal total = account.getTotal();
synchronized(account) {
  BigDecimal newTotal = total.multiply(INTEREST_RATE);
  account.setTotal(newTotal);
}
Compiler Optimisations
Lock Coarsening

synchronized(account) {
  BigDecimal total = account.getTotal();
  BigDecimal newTotal = total.multiply(INTEREST_RATE);
  account.setTotal(newTotal);
}
Compiler Optimisations
Lock Elision

public static void main(String... args) {
  ConcurrentMap<String,Integer> map;
  map = new ConcurrentHashMap<String, Integer>();
  map.put("one", Integer.valueOf(1));
  map.put("two", Integer.valueOf(2));
  map.put("three", Integer.valueOf(3));
}
Compiler Optimisations
Lock Elision

public class Foo implements Runnable {
  public void run() {
     synchronized(new Object()) {
        //Do something
     }
  }
}
What is a Memory Model

 A model to describe thread interaction with memory.
 Multiprocessors have different memory models.
    Inconsistently weak
 Enables to instruct memory fencing.
 Helps to write date race free
 Preserving program order.
Java Memory Model

 A Memory Model for consistent thread behaviour with
 memory for all CPU architectures
     Alpha
     RISC
     PowerPC
     x86
     AMD64
 Pioneering
 Influential
Java Memory Model

 History
    Initially broken
         volatile was not very volatile
         final was not very final
 Developers originally worked around locks.
 Huge open research area
 Constantly finding new ways to improve the JMM.
 People looking to go towards different ways of reasoning.
Java Memory Model

Goals

1. Allow as many compiler and hardware optimisations as
possible.

2. Provide balance between optimisations and correctly
synchronised code.

3. Provide developers to write and reason about multithreaded
code.
Happens-Before Ordering
Java's synchronized keyword
public class BankAccount {

    private BigDecimal total = new BigDecimal(0);

    public BigDecimal withdraw(BigDecimal amount) {
      total = total.minus(amount);
      return total;
    }

    public BigDecimal deposit(BigDecimal amount) {
      total = total.add(amount);
      return total;
    }

    public BigDecimal total() { return total; }

}
Symmetrical Multiprocessing
    deposit(200)   withdraw(100) total() == 0
       T1              T2            T3




   BankAccount account = new BankAccount();
Java's synchronized keyword
public class BankAccount {

    private BigDecimal total = new BigDecimal(0);

    public synchronized BigDecimal withdraw(BigDecimal amount) {
      total = total.minus(amount);
      return total;
    }

    public synchronized BigDecimal deposit(BigDecimal amount) {
      total = total.add(amount);
      return total;
    }

    public synchronized BigDecimal total() {return total;}

}
Symmetrical Multiprocessing
    deposit(200)   withdraw(100) total() == 100
       T1              T2            T3




   BankAccount account = new BankAccount();
Java's volatile keyword

@Singleton
class FooFactory {

  private Foo foo;

  public Foo getFoo() {
    if (foo == null) {
        synchronized(this) {
           if (foo == null) {
              foo = new Foo("bar");
          }
        }
    }
    return foo;
Java's volatile keyword
class Foo {

    private String name;

    public Foo(String name) {
      setName(name);
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getName() {
      return name;
    }

}
Symmetrical Multiprocessing
    new Foo()   name == null   name == "bar"




                foo = "bar"
Java's volatile keyword

@Singleton
class FooFactory {

  private volatile Foo foo;

  public Foo getFoo() {
    if (foo == null) {
        synchronized(this) {
           if (foo == null) {
              foo = new Foo();
           }
        }
    }
    return foo;
Symmetrical Multiprocessing
  new Foo("bar")   name == "bar"   name == "bar"




                   name == "bar"
Java's volatile keyword

@ThreadSafe
class FooFactory {

    private static class FooHelper {
       public static Foo foo = new Foo();
    }

    public static Foo getFoo() {
      return FooHelper.foo;
    }

}
Java's final keyword

class MeaningOfLife {

    private final int answer;

    public MeaningOfLife(int answer){
      this.answer = answer;
    }

    public int answer() {
      return this.answer;
    }

}
Final
   int answer = 42   int answer = 42   int answer = 42




   MeaningOfLife life = new MeaningOfLife(42);
Summary

Memory ordering can change the program
order of multithreaded code.
Memory barriers inhibits optimisations for
correct synchronisation.
Java Concurrency Constructs: ensures mutual
exclusion and memory visibility
Happens-Before ordering: any subsequent
lock acquisitions will see changes made by
previous lock releases.
Ad

More Related Content

Viewers also liked (20)

The Java memory model made easy
The Java memory model made easyThe Java memory model made easy
The Java memory model made easy
Rafael Winterhalter
 
Java GC - Pause tuning
Java GC - Pause tuningJava GC - Pause tuning
Java GC - Pause tuning
ekino
 
Java gc
Java gcJava gc
Java gc
Niit
 
[BGOUG] Java GC - Friend or Foe
[BGOUG] Java GC - Friend or Foe[BGOUG] Java GC - Friend or Foe
[BGOUG] Java GC - Friend or Foe
SAP HANA Cloud Platform
 
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Anna Shymchenko
 
Java Garbage Collection(GC)- Study
Java Garbage Collection(GC)- StudyJava Garbage Collection(GC)- Study
Java Garbage Collection(GC)- Study
Dhanu Gupta
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
Scheidt & Bachmann
 
Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"
Ciklum Minsk
 
Java Memory Model
Java Memory ModelJava Memory Model
Java Memory Model
Łukasz Koniecki
 
Java Memory Consistency Model - concepts and context
Java Memory Consistency Model - concepts and contextJava Memory Consistency Model - concepts and context
Java Memory Consistency Model - concepts and context
Tomek Borek
 
Java gc and JVM optimization
Java gc  and JVM optimizationJava gc  and JVM optimization
Java gc and JVM optimization
Rajan Jethva
 
What you need to know about GC
What you need to know about GCWhat you need to know about GC
What you need to know about GC
Kelum Senanayake
 
Java memory model
Java memory modelJava memory model
Java memory model
Michał Warecki
 
Java GC, Off-heap workshop
Java GC, Off-heap workshopJava GC, Off-heap workshop
Java GC, Off-heap workshop
Valerii Moisieienko
 
How long can you afford to Stop The World?
How long can you afford to Stop The World?How long can you afford to Stop The World?
How long can you afford to Stop The World?
Java Usergroup Berlin-Brandenburg
 
JVM及其调优
JVM及其调优JVM及其调优
JVM及其调优
zhongbing liu
 
Tuning Java GC to resolve performance issues
Tuning Java GC to resolve performance issuesTuning Java GC to resolve performance issues
Tuning Java GC to resolve performance issues
Sergey Podolsky
 
GC Tuning in the HotSpot Java VM - a FISL 10 Presentation
GC Tuning in the HotSpot Java VM - a FISL 10 PresentationGC Tuning in the HotSpot Java VM - a FISL 10 Presentation
GC Tuning in the HotSpot Java VM - a FISL 10 Presentation
Ludovic Poitou
 
淺談 Java GC 原理、調教和 新發展
淺談 Java GC 原理、調教和新發展淺談 Java GC 原理、調教和新發展
淺談 Java GC 原理、調教和 新發展
Leon Chen
 
Java GC
Java GCJava GC
Java GC
Ray Cheng
 
Java GC - Pause tuning
Java GC - Pause tuningJava GC - Pause tuning
Java GC - Pause tuning
ekino
 
Java gc
Java gcJava gc
Java gc
Niit
 
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Вячеслав Блинов «Java Garbage Collection: A Performance Impact»
Anna Shymchenko
 
Java Garbage Collection(GC)- Study
Java Garbage Collection(GC)- StudyJava Garbage Collection(GC)- Study
Java Garbage Collection(GC)- Study
Dhanu Gupta
 
Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"Николай Папирный Тема: "Java memory model для простых смертных"
Николай Папирный Тема: "Java memory model для простых смертных"
Ciklum Minsk
 
Java Memory Consistency Model - concepts and context
Java Memory Consistency Model - concepts and contextJava Memory Consistency Model - concepts and context
Java Memory Consistency Model - concepts and context
Tomek Borek
 
Java gc and JVM optimization
Java gc  and JVM optimizationJava gc  and JVM optimization
Java gc and JVM optimization
Rajan Jethva
 
What you need to know about GC
What you need to know about GCWhat you need to know about GC
What you need to know about GC
Kelum Senanayake
 
Tuning Java GC to resolve performance issues
Tuning Java GC to resolve performance issuesTuning Java GC to resolve performance issues
Tuning Java GC to resolve performance issues
Sergey Podolsky
 
GC Tuning in the HotSpot Java VM - a FISL 10 Presentation
GC Tuning in the HotSpot Java VM - a FISL 10 PresentationGC Tuning in the HotSpot Java VM - a FISL 10 Presentation
GC Tuning in the HotSpot Java VM - a FISL 10 Presentation
Ludovic Poitou
 
淺談 Java GC 原理、調教和 新發展
淺談 Java GC 原理、調教和新發展淺談 Java GC 原理、調教和新發展
淺談 Java GC 原理、調教和 新發展
Leon Chen
 

More from Skills Matter (20)

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
Skills Matter
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
Skills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Skills Matter
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
Skills Matter
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Skills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Skills Matter
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
Skills Matter
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
Skills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
Skills Matter
 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
Skills Matter
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
Skills Matter
 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
Skills Matter
 
Lug presentation
Lug presentationLug presentation
Lug presentation
Skills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
Skills Matter
 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
Skills Matter
 
5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
Skills Matter
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
Skills Matter
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Skills Matter
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
Skills Matter
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Skills Matter
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Skills Matter
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Skills Matter
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Skills Matter
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Skills Matter
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Skills Matter
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
Skills Matter
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
Skills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
Skills Matter
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
Skills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
Skills Matter
 
Ad

Recently uploaded (20)

2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx2025-05-Q4-2024-Investor-Presentation.pptx
2025-05-Q4-2024-Investor-Presentation.pptx
Samuele Fogagnolo
 
Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025Splunk Security Update | Public Sector Summit Germany 2025
Splunk Security Update | Public Sector Summit Germany 2025
Splunk
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)Into The Box Conference Keynote Day 1 (ITB2025)
Into The Box Conference Keynote Day 1 (ITB2025)
Ortus Solutions, Corp
 
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In FranceManifest Pre-Seed Update | A Humanoid OEM Deeptech In France
Manifest Pre-Seed Update | A Humanoid OEM Deeptech In France
chb3
 
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager APIUiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPath Community Berlin: Orchestrator API, Swagger, and Test Manager API
UiPathCommunity
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded DevelopersLinux Support for SMARC: How Toradex Empowers Embedded Developers
Linux Support for SMARC: How Toradex Empowers Embedded Developers
Toradex
 
Procurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptxProcurement Insights Cost To Value Guide.pptx
Procurement Insights Cost To Value Guide.pptx
Jon Hansen
 
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptxSpecial Meetup Edition - TDX Bengaluru Meetup #52.pptx
Special Meetup Edition - TDX Bengaluru Meetup #52.pptx
shyamraj55
 
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
AI EngineHost Review: Revolutionary USA Datacenter-Based Hosting with NVIDIA ...
SOFTTECHHUB
 
How analogue intelligence complements AI
How analogue intelligence complements AIHow analogue intelligence complements AI
How analogue intelligence complements AI
Paul Rowe
 
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep DiveDesigning Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
ScyllaDB
 
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-UmgebungenHCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
HCL Nomad Web – Best Practices und Verwaltung von Multiuser-Umgebungen
panagenda
 
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Enhancing ICU Intelligence: How Our Functional Testing Enabled a Healthcare I...
Impelsys Inc.
 
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdfThe Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
The Evolution of Meme Coins A New Era for Digital Currency ppt.pdf
Abi john
 
Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.Greenhouse_Monitoring_Presentation.pptx.
Greenhouse_Monitoring_Presentation.pptx.
hpbmnnxrvb
 
Drupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy ConsumptionDrupalcamp Finland – Measuring Front-end Energy Consumption
Drupalcamp Finland – Measuring Front-end Energy Consumption
Exove
 
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptxDevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
DevOpsDays Atlanta 2025 - Building 10x Development Organizations.pptx
Justin Reock
 
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath MaestroDev Dives: Automate and orchestrate your processes with UiPath Maestro
Dev Dives: Automate and orchestrate your processes with UiPath Maestro
UiPathCommunity
 
Ad

Java Memory Model

  • 1. Java Memory Model The enigma of Java James Perry
  • 2. About Me Software Engineer at Barclays Capital http://www.natureinspiredcode.com http://github.com/natureinspired/8queen-ea g-graphs Twitter: @nature_inspired
  • 3. JMM in a Nutshell JMM is a universal contract for how threads interact with memory in Java programs. Happens-Before ordering: "official" reasoning for thread interaction. synchronized provides mutual exclusion and memory visibility. volatile provides atomic memory visibility.
  • 4. public class SleepyThreadDemo { private static boolean awake; public static void main(String[] args) throws InterruptedException { Thread sleepyThread = new Thread(new Runnable() { public void run() { int zCount = 0; while(!awake) { zCount++; } } }); sleepyThread.start(); TimeUnit.SECONDS.sleep(1); awake = true; } }
  • 5. public class SleepyThreadDemo { private static boolean awake; public static void main(String[] args) throws InterruptedException { Thread sleepyThread = new Thread(new Runnable() { public void run() { int zCount = 0; if (!awake) { while(true) { zCount++; } } } }); sleepyThread.start(); TimeUnit.SECONDS.sleep(1); awake = true; }
  • 6. Causality Cause Symmetric Multiprocessing (SMP) Memory Ordering Memory Barriers Compiler Optimisation Effect History Objectives Happens-Before Ordering Concurrency Constructs
  • 7. Symmetrical Multiprocessing Memory Contention Cache Coherency
  • 9. Symmetrical Multiprocessing foo = 42 foo = 1 foo = 12 public static int foo = 1
  • 10. Symmetrical Multiprocessing foo = 42 foo = 42 foo = 42 public static int foo = 42
  • 12. Memory Ordering 1. CPU 0 executes a=1. int a = 1; 2. CPU 0 looks “a” up in the cache, and finds int b = a + 1; that it is missing. assert(b == 2) 3. CPU 0 therefore sends a “read invalidate” mes- sage in order to get exclusive ownership of the cache line containing “a”. 4. CPU 0 records the store to “a” in its store buffer. 5. CPU 1 receives the “read invalidate” message, and responds by transmitting the cache line and removing that cacheline from its cache.
  • 13. Memory Ordering 6. CPU 0 starts executing the b=a+1. int a = 1; 7. CPU 0 receives the cache line from CPU 1, int b = a + 1; which still has a value of zero for “a”. assert(b == 2) 8. CPU 0 loads “a” from its cache, finding the value zero. 9. CPU 0 applies the entry from its store queue to the newly arrived cache line, setting the value of “a” in its cache to one. 10. CPU 0 adds one to the value zero loaded for “a” above, and stores it into the cache line containing “b” (which we will assume is already owned by CPU 0). 11. CPU 0 executes assert(b==2), which fails.
  • 14. Memory Ordering 1. CPU 0 executes a=1. The cache line is not in CPU 0’s cache, so CPU 0 places the new value of “a” in its store @Singleton buffer and transmits a “read invalidate” class FooBar { message. 2. CPU 1 executes while(b==0)continue, private int a, b; but the cache line containing “b” is not in its cache. It therefore transmits a “read” message. public void foo() { 3. CPU 0 executes b=1. It already owns a = 1; this cache line, so it stores the new b = 1; value of “b” in its cache line. } 4. CPU 0 receives the “read” message, and transmits the cache line public void bar() { containing the now-updated value of while(b==0) continue; “b” to CPU 1, also marking the line as assert(a==1); “shared” in its own cache. } }
  • 15. Memory Ordering 5. CPU 1 receives the cache line containing “b” and installs it in its cache. 6. CPU 1 can now finish executing while (b==0) continue, and since it finds that @Singleton the value of “b” is 1, it proceeds to the class FooBar { next statement. 7. CPU 1 executes the assert(a==1), private int a, b; and, since CPU 1 is working with the old value of “a”, this assertion fails. public void foo() { 8. CPU 1 receives the “read invalidate” a = 1; message, and transmits the cache line containing “a” to CPU 0 and invalidates b = 1; this cache line from its own cache. But it } is too late. 9. CPU 0 receives the cache line public void bar() { containing “a” and applies the buffered while(b==0) continue; store just in time to fall victim to CPU 1’s assert(a==1); failed assertion. } }
  • 16. 1. CPU 0 executes a=1. The cache line is not in Memory Ordering CPU 0’s cache, so CPU 0 places the new value of “a” in its store buffer and transmits a “read invalidate” message. @Singleton 2. CPU 1 executes while(b==0)continue, but class FooBar { the cache line containing “b” is not in its cache. It therefore transmits a “read” message. private int a, b; 3. CPU 0 executes fence(), and marks all current store-buffer entries (namely, the a=1). public void foo() { 4. CPU 0 executes b=1. It already owns this a = 1; cache line, but there is a marked entry in the fence(); store buffer. Therefore, rather than store the new value of “b” in the cache line, it instead b = 1; places it in the store buffer (but in an } unmarked entry). 5. CPU 0 receives the “read” message, and trans- mits the cache line containing the public void bar() { original value of “b” to CPU 1. It also marks while(b==0) continue; its own copy of this cache line as “shared”. assert(a==1); 6. CPU 1 receives the cache line containing “b” and installs it in its cache. } 7. CPU 1 can now finish executing while(b==0) continue, but since it finds that the value of } 'b' i still 0, it repeats the while statement. The new value of 'b' is safely hidden in CPU 0's store buffer.
  • 17. Memory Fencing 8. CPU 1 receives the “read invalidate” message, and transmits the cache line containing 'a' to CPU 0 and invalidates this @Singleton cache line from its own cache. class FooBar { 9. CPU 0 receives the cache line containing 'a' and applies the buffered store. 10. Since the store to 'a' was the only entry in private int a, b; the store buffer that was marked by fence(), CPU 0 can also store the new value 'b' - expect for the fact that the cache line public void foo() { containing 'b' is now in 'shared' state. a = 1; 11. CPU 0 therefore sends an 'invalidate fence(); message to CPU 1'. 12. CPU 1 receives the 'invalidate' message, b = 1; invalidates the cache line containing 'b' from } its cache, and sends an 'acknowledgement' message to CPU 0. 13. CPU 1 executes while(b==0)continue, public void bar() { but the cache line containing 'b' is not in while(b==0) continue; cache. It therefore transmits a 'read' message assert(a==1); to CPU 0. } }
  • 18. Memory Fencing 14. CPU 0 receives the 'acknowledgement' message, and puts the cache line containing 'b' @Singleton into the 'exclusive' state. CPU 0 now stores the new value of 'b' into the cache line. class FooBar { 15. CPU 0 receives the 'read' message, and transmits the cache line containing the original private int a, b; value of 'b' to CPU 1. It also marks its own copy of this cache as 'shared'. 16. CPU 1 receives the cache line containing 'b' public void foo() { and installs it in its cache. a = 1; 17. CPU 1 can now finish executing while (b==0)continue and since it finds that the value fence(); of 'b' is 1, it proceeds to the next statement. b = 1; 18. CPU 1 executes the assert(a==1) but the } cache line containing 'a' is no longer in its cache. Once it gets this cache from CPU 0, it will be working with the up-to-date value of 'a', public void bar() { thus assertion passes. while(b==0) continue; assert(a==1); } }
  • 19. Compiler Optimisations Loop Fusion int i = 0, size = 100; int[] a = new int[size], b = new int[size]; for (i = 0; i < size; i++) { a[i] = 1; } for (i = 0; i < size; i++) { b[i] = 2; }
  • 20. Compiler Optimisations Loop Fusion int i = 0, size = 100; int[] a = new int[size], b = new int[size]; for (i = 0; i < size; i++) { a[i] = 1; b[i] = 2; }
  • 21. Compiler Optimisations Loop Fission int i = 0, size = 100; int[] a = new int[size], b = new int[size]; for (i = 0; i < size; i++) { a[i] = 1; b[i] = 2; }
  • 22. Compiler Optimisations Loop Fission int i = 0, size = 100; int[] a = new int[size], b = new int[size]; for (i = 0; i < size; i++) { a[i] = 1; } for (i = 0; i < size; i++) { b[i] = 2; }
  • 23. Compiler Optimisations Lock Coarsening BigDecimal total = account.getTotal(); synchronized(account) { BigDecimal newTotal = total.multiply(INTEREST_RATE); account.setTotal(newTotal); }
  • 24. Compiler Optimisations Lock Coarsening synchronized(account) { BigDecimal total = account.getTotal(); BigDecimal newTotal = total.multiply(INTEREST_RATE); account.setTotal(newTotal); }
  • 25. Compiler Optimisations Lock Elision public static void main(String... args) { ConcurrentMap<String,Integer> map; map = new ConcurrentHashMap<String, Integer>(); map.put("one", Integer.valueOf(1)); map.put("two", Integer.valueOf(2)); map.put("three", Integer.valueOf(3)); }
  • 26. Compiler Optimisations Lock Elision public class Foo implements Runnable { public void run() { synchronized(new Object()) { //Do something } } }
  • 27. What is a Memory Model A model to describe thread interaction with memory. Multiprocessors have different memory models. Inconsistently weak Enables to instruct memory fencing. Helps to write date race free Preserving program order.
  • 28. Java Memory Model A Memory Model for consistent thread behaviour with memory for all CPU architectures Alpha RISC PowerPC x86 AMD64 Pioneering Influential
  • 29. Java Memory Model History Initially broken volatile was not very volatile final was not very final Developers originally worked around locks. Huge open research area Constantly finding new ways to improve the JMM. People looking to go towards different ways of reasoning.
  • 30. Java Memory Model Goals 1. Allow as many compiler and hardware optimisations as possible. 2. Provide balance between optimisations and correctly synchronised code. 3. Provide developers to write and reason about multithreaded code.
  • 32. Java's synchronized keyword public class BankAccount { private BigDecimal total = new BigDecimal(0); public BigDecimal withdraw(BigDecimal amount) { total = total.minus(amount); return total; } public BigDecimal deposit(BigDecimal amount) { total = total.add(amount); return total; } public BigDecimal total() { return total; } }
  • 33. Symmetrical Multiprocessing deposit(200) withdraw(100) total() == 0 T1 T2 T3 BankAccount account = new BankAccount();
  • 34. Java's synchronized keyword public class BankAccount { private BigDecimal total = new BigDecimal(0); public synchronized BigDecimal withdraw(BigDecimal amount) { total = total.minus(amount); return total; } public synchronized BigDecimal deposit(BigDecimal amount) { total = total.add(amount); return total; } public synchronized BigDecimal total() {return total;} }
  • 35. Symmetrical Multiprocessing deposit(200) withdraw(100) total() == 100 T1 T2 T3 BankAccount account = new BankAccount();
  • 36. Java's volatile keyword @Singleton class FooFactory { private Foo foo; public Foo getFoo() { if (foo == null) { synchronized(this) { if (foo == null) { foo = new Foo("bar"); } } } return foo;
  • 37. Java's volatile keyword class Foo { private String name; public Foo(String name) { setName(name); } public void setName(String name) { this.name = name; } public String getName() { return name; } }
  • 38. Symmetrical Multiprocessing new Foo() name == null name == "bar" foo = "bar"
  • 39. Java's volatile keyword @Singleton class FooFactory { private volatile Foo foo; public Foo getFoo() { if (foo == null) { synchronized(this) { if (foo == null) { foo = new Foo(); } } } return foo;
  • 40. Symmetrical Multiprocessing new Foo("bar") name == "bar" name == "bar" name == "bar"
  • 41. Java's volatile keyword @ThreadSafe class FooFactory { private static class FooHelper { public static Foo foo = new Foo(); } public static Foo getFoo() { return FooHelper.foo; } }
  • 42. Java's final keyword class MeaningOfLife { private final int answer; public MeaningOfLife(int answer){ this.answer = answer; } public int answer() { return this.answer; } }
  • 43. Final int answer = 42 int answer = 42 int answer = 42 MeaningOfLife life = new MeaningOfLife(42);
  • 44. Summary Memory ordering can change the program order of multithreaded code. Memory barriers inhibits optimisations for correct synchronisation. Java Concurrency Constructs: ensures mutual exclusion and memory visibility Happens-Before ordering: any subsequent lock acquisitions will see changes made by previous lock releases.