Java Memory Model
-
Upload
instinctools -
Category
Software
-
view
210 -
download
0
Transcript of Java Memory Model
Java Memory Model
Java Memory Model
Java Memory Model is the model that describes the behavior of memory in Java program. The main task of this model is to reply the question thatcan distinguish the concrete definition of «read» in theprogram.
Java Memory ModelIn the case of single-threaded languages usually the memory pattern is quite simple:
That is why the memory model is often understood as the model of memory behavior pattern in multi-threaded applications. But in some cases it is required also for judging about the pattern of single-threaded applications.
int x = 10;int b = x;int c = b + x;x = c — b;c = b;
Java Memory Model
In order to develop a multi-threaded application we need to understand:
● In what order the actions are executed in the application;● How does the data sharing between threads?
Java Memory Model: Access atomicity
We would like to make every action at the field atomic:
long value = 0;
value = -1; System.out.println(value);
// 0, -1,// 0xFFFFFFFF00000000 | 18446744069414584000
Java Memory Model: Access atomicity
In order to provide atomicity, we need to have this support from hardware.
Possible problems:– The absence of hardware operations for read/record of big values;– The request to memory’s sub-system, for example, at х86 you can’t
place the data point at crossing of cashlines.
Java Memory Model: Access atomicity
In the current version of JMM we can see that the work with all primitives except long/double has to be atomic by default. For the activation of atomicity of long/double it is required to use volatile.
Java Memory Model: Word tearing
We would like to make all operations at fields/array elements/etc. to be independent:
int[] array = new int[4]; array[0] = 1; array[1] = 1;
array[0] = 2; array[1] = 2;
int a1 = array[0];int a2 = array[1];
System.out.println(a1 == a2);
<term> <term> <join both>
Java Memory Model: Word tearing
To provide the independent read/record, unexpectedly we need to have the same kind of support from hardware.
Possible problems:– The absence of hardware operations for read/record of too small
data points. Usually this is for N < 8 bit.
Solution:– The minimal data type has to be N >= 8 bit and then we can make
independent read/record for all types of data.
Java Memory Model: Word tearing
We wonder what will happen in such a case?
BitSet bitSet = new BitSet();
bitSet.set(1); bitSet.set(2);
boolean b1 = bitSet.get(1);boolean b2 = bitSet.get(2);
System.out.println(b1 == b2);
<term> <term> <join both>
Java Memory Model: Reordering
We would like all actions in the program to be executed in the same order as the one written by a programmer in the initial code. But some types of optimization require certain changes:
int x = 0; int y = 0;
x = 10;
println(y);
y = 20;
println(x);
println(20); println(10);
...
Java Memory Model: Reordering
int x = 0; int y = 0;
int v1 = x;
int v2 = y;
y = 20;x = 10;
int v2 = y;
int v1 = x;
y = 20;x = 10;
int x = 0; int y = 0;
Runtime and iron don’t have the All-Seeing Eye to find what changes never break the logics globally, they can define correctness only of the local order — Program Order.
Java Memory Model: Synchronization Actions
JMM allows multiple types of optimization with appliance of shifts and offers the set of SA for limiting this:
● volatile read/write● lock/unlock monitor● first/last action in the thread ● the action that launches the thread● the action that finds the interrupted thread (Thread.join().
Thread.isInterrupted(),etc.)
Java Memory Model: Synchronization Actions
JMM forbids to change the work order with SA. That’s why we can say for sure in what order the actions at SA elements happen in this example:
volatile int x = 0; volatile int y = 0;
y = 5;
println(x);
x = 5;
println(y);
Java Memory Model: Synchronization Actions
volatile int x = 0; volatile int y = 0;
y = 5;
println(x);
x = 5;
println(y);
Also SA elements help to connect the sequences of actions between different threads, in such way forming Synchronization Order:
Java Memory Model: Happens Before
But let’s examine the case, when we have actions not only at SA elements, what will happen with x?
int x = 0; volatile int y = 0;
int v1 = y;
int v2 = x;
x = 5;
y = 5;
Java Memory Model: Happens Before
Right now let’s examine the case, when reading of v1 have identified 5 in y, then Happens Before works in such way, when v2 equals 5:
int x = 0; volatile int y = 0;
int v1 = y;
int v2 = x;
x = 5;
y = 5;
Java Memory Model: Happens Before
Right now let’s examine the case when v1 read in y - 0, in this case v2 can be equal whether 0 or 5:
int x = 0; volatile int y = 0;
int v1 = y;
int v2 = x;
x = 5;
y = 5;
Java Memory Model: Happens Before
Now focus on another case:
volatile int a = 0; int b, c, d, e;
b = 1;
c = 2;
a = 5;
d = 3;
e = 4;
int v1 = d;
int v2 = e;
int v3 = a;
int v4 = b;
int v5 = c;
Java Memory Model: Happens Before
Let’s take a closer look at one more case:
volatile int a = 0, b; int c, d, e, g;
c = 1;
d = 2;
a = 3;
int v1 = b;
int v2 = e;
int v3 = g;
e = 4;
g = 5;
b = 6;
int v1 = a;
int v2 = c;
int v3 = d;
Java Memory Model: Happens Before
public class С<T> {
private T val;
public synchronized void setVal(final T val) { if(this.val == null) this.val = val; }
public synchronized T getVal() { return val; }}
Java Memory Model: Happens Before
public class С<T> {
private T val;
public synchronized void setVal(final T val) { if(this.val == null) this.val = val; }
public T getVal() { return val; }}
Java Memory Model: Happens Before
public class С<T> {
static volatile int BARRIER; int sink;
private T val;
public synchronized void setVal(final T val) { if(this.val == null) this.val = val; }
public T getVal() { sink = BARRIER; return val; }}
Java Memory Model: Happens Before
public class С<T> {
private volatile T val;
public synchronized void setVal(final T val) { if(this.val == null) this.val = val; }
public T getVal() { return val; }}
Java Memory Model: Happens Beforepublic class C<T> { private T val; public synchronized void setVal(final T val) { if(val == null) { VarHandle.releaseFence(); this.val = val; VarHandle.fullFence(); } }
public T getVal() { T val = this.val; VarHandle.acquireFence(); return val; }}
May The Force Be With You!