The `Java happens before guarantee` is a set of rules that govern how the Java VM and CPU is allowed to reorder instructions for performance gains. It makes it possible for threads to rely on when a variable value is synchronized to or from main memory, and which other variables have been synchronized at the same time. The Java happens before guarantee is centered around access to `volatile` variables and variables accessed from within `synchronized` blocks # Instruction Reordering Modern CPUs have the ability to execute instructions in parallel when the instructions do not depend on each other. For example, the following two instructions do not depend on each other, therefore they can be executed in parallel ``` a = b + c d = e + f ``` However, the following two instructions cannot easily be executed in parallel because the second instruction depends on the result of the first instruction. ``` a = b + c d = a + e ``` Reordering of instructions can increase parallel execution of instructions in the CPU. Increased parallelization means increased performance. Instruction reordering is allowed for the Java VM and the CPU as long as the semantics of the program do not change. The end result has to be the same as if the instructions were executed in the exact order they are listed in the source code. ## The Java Volatile Visibility Guarantee The Java `volatile` keyword provides some visibility guarantees for when writes to, and reads of, volatile variables result in synchronization of the variable's value to and from main memory. The synchronization to and from main memory is what makes the value visible to other threads. Instruction reordering may break the volatile visibility guarantee. That is why we have the `Java volatile happens before guarantee`, to place some restrictions on instruction reordering. ### The Java Volatile Write Visibility Guarantee Writing to a Java `volatile` variable will result in its updated value being written directly to main memory. Additionally, all variables visible to the thread writing to the volatile variable will also be synchronized to main memory. To illustrate the Java volatile write visibility guarantee, look at this example: ``` this.nonVolatileVarA = 34; this.nonVolatileVarB = new String("Text"); this.volatileVarC = 300; ``` When the third instruction in the example above writes to the volatile variable `volatileVarC`, the values of the two non-volatile variables will also be synchronized to main memory. This is because these variables are visible to the thread when writing to the volatile variable. ### The Java Volatile Read Visibility Guarantee When the value of a Java volatile variable is read, it is guaranteed to be read directly from main memory. Furthermore, all the variables visible to the thread reading the volatile variable will also have their values refreshed from main memory. To illustrate the Java volatile read visibility guarantee look at this example: ``` c = other.volatileVarC; b = other.nonVolatileB; a = other.nonVolatileA; ``` When `other.volatileVarC` is read in from main memory, the `other.nonVolatileB` and `other.nonVolatileA` are also read in from main memory. ## The Java Volatile Happens Before Guarantee The `Java volatile happens before guarantee` sets some restrictions on instruction reordering around volatile variables. ### Happens Before Guarantee for Writes to Volatile Variable The volatile write happens before guarantee puts restrictions on what kind of instruction reordering is allowed around writes to volatile variables. * A write to a non-volatile or volatile variable that happens before a write to a volatile variable is guaranteed to happen before the write to that volatile variable. ### Happens Before Guarantee for Reads of Volatile Variables Volatile variables in Java has a similar happens before guaranteed for reads of volatile variables. * A read of a volatile variable will happen before any subsequent reads of volatile and non-volatile variables. # The Java Synchronize Visibility Guarantee The synchronized block provides visibility guarantees that are similar to those of Java volatile variables. ## Java Synchronized Entry Visibility Guarantee When a thread enters a synchronized block, all variables visible to the thread are refreshed from main memory. ## Java Synchronized Exit Visibility Guarantee When a thread exits a synchronized block, all variables visible to the thread are written back to main memory. # Java Synchronized Happens Before Guarantee Java synchronized blocks provide two happens before guarantees: one guarantee related to the beginning of a synchronized block and another guarantee related to the end of a synchronized block. ## Java Synchronized Block Beginning Happens Before Guarantee * None of the reads of the variables can be reordered to appear before the beginning of a the synchronized block. If a read of a variable was reordered to appear before the beginning of the synchronized block, you would lose the guarantee of the variable values being refreshed from main memory. ## Java Synchronize Block End Happens Before Guarantee * None of the writes to the variables can be reordered to appear after the end of the synchronized block. If the writes to the variables were reordered to to appear after the end of the synchronized block, you would lose the guarantee of the variable values being written back to main memory.