Java Concurrency (iv) orderly

An instruction rearrangement

Instruction sequence formed after sequential program compiler compiles the computer execution instruction, in general, the output of this instruction sequence will result of the determination; to ensure that each has an execution result of determination. However, under normal circumstances, CPU and compiler in order to improve the efficiency of program execution, allows instruction in accordance with certain rules to optimize, in some cases, this optimization will bring logic to perform a number of issues, the main reason is that the code there is a certain sequence of logic between, in the case of concurrent execution, ambiguity occurs, i.e., in different execution logic information will get different results.

Code examples:

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (null == singleton) {
            synchronized (Singleton.class) {
                if (null == singleton) {
                    singleton = new Singleton();
                }
            }
        }

        return singleton;
    }
}
复制代码

For the following code:

singleton = new Singleton();
复制代码

We thought the order is:
1. Allocate a block of memory
2. Initialize Singleton objects in memory
3. Then assign an address to the instance variable M

But not actually view the JAVA byte code:

public class com.javashizhan.concurrent.demo.base.Singleton {
  public static com.javashizhan.concurrent.demo.base.Singleton getInstance();
    Code:
       0: aconst_null
       1: getstatic     #2                  // Field singleton:Lcom/javashizhan/concurrent/demo/base/Singleton;
       4: if_acmpne     39
       7: ldc           #3                  // class com/javashizhan/concurrent/demo/base/Singleton
       9: dup
      10: astore_0
      11: monitorenter
      12: aconst_null
      13: getstatic     #2                  // Field singleton:Lcom/javashizhan/concurrent/demo/base/Singleton;
      16: if_acmpne     29
      19: new           #3                  // class com/javashizhan/concurrent/demo/base/Singleton
      22: dup
      23: invokespecial #4                  // Method "<init>":()V
      26: putstatic     #2                  // Field singleton:Lcom/javashizhan/concurrent/demo/base/Singleton;
      29: aload_0
      30: monitorexit
      31: goto          39
      34: astore_1
      35: aload_0
      36: monitorexit
      37: aload_1
      38: athrow
      39: getstatic     #2                  // Field singleton:Lcom/javashizhan/concurrent/demo/base/Singleton;
      42: areturn
    Exception table:
       from    to  target type
          12    31    34   any
          34    37    34   any
}
复制代码

See 19 to 26, the actual order is:
1. Allocate a memory
2. The address assigned to the instance variable M
3. Finally initialization M Singleton object in memory.

Problems due to the sequential instructions, concurrent multi-threading thread A executed prior to a thread switch 26 has occurred, then thread B is found not established null == singleton, singleton acquired, but this time is not initialized singleton finished, it will lead to a null pointer abnormal.

Two, Happens-Before rules

Happens-Before constrained optimization compiler's behavior, although allows the compiler to optimize, but requires the compiler to optimize certain Happens-Before comply with the rules.

1. The program sequence rules
in a thread, in program order, the previous operation Happens-Before any subsequent operation. In front of a variable modified procedure must be visible for a subsequent operation.

2.volatile variable rules write to a volatile variable, Happens-Before subsequent reading of the volatile variable operation.

3. If the transmission of the A Happens-Before to B, B Happens-Before for C, then to C. A Happens-Before

4. The lock rules
for unlocking a lock to lock Happens-Before this lock.

5. Start rule main thread after thread A promoter thread B, sub-thread B can see the operation before the main thread thread B promoter.

6. Thread Rules join
the main thread wait for the child A complete thread B (main thread join method is implemented by calling the sub-thread B), when the child thread B is completed (join () method returns the main thread A), the main thread can be seen operation sub-thread.

7. thread interrupts regular
calls to thread interrupt () method first occurred in the interrupted thread code detection interrupt occurrence of the event can be detected by Thread.interrupted () method if an interrupt occurs.

8. End Rule objects
of an object initialization completion (execution end constructor) preceding it occurs finalize () method starts.

end.


Site: javashizhan.com/


Micro-channel public number:


Guess you like

Origin juejin.im/post/5d947ea26fb9a04e3f4ef8d1