Java geek

Related reading:

Concurrent Programming in Java (a) knowledge map

Java Concurrency programming (2) Atomic Java concurrency programming (3) Visibility Java Concurrency programming (5) Introduction to Java Concurrency programming (6) Introduction to Synchronized Java concurrency programming (7) Easy to understand wait and notify and use scenarios Introduction to Concurrent Programming in Java (8) Thread Lifecycle Introduction to Concurrent Programming in Java (9) Deadlock and deadlock bits Introduction to Concurrent programming in Java (10) Lock Optimization Introduction to Concurrent programming in Java (11) Flow limiting Scenarios and Spring Flow Limiter Implementation introduction to Concurrent programming in Java (12) Producer and Consumer Patterns – Code templates Java Concurrent programming introduction (13) Read/write lock and cache template Java concurrent programming Introduction (14) CountDownLatch Application Scenario Java concurrent programming Introduction (15) CyclicBarrier application scenario Java concurrent programming Introduction (16) Understand thread pool differences Introduction to Concurrent Programming in Java (17) 一 figure Master common classes and interfaces for threads Concurrent programming in Java (18) Rediscussion of thread safety Concurrent programming in Java (19) Asynchronous task scheduling tool CompleteFeature Concurrent programming in Java (20) Common locking scenarios and locking tools


1. Order

Definition 1.1.

In the code sequence structure, you can intuitively specify the code execution order, that is, from top to bottom. However, the compiler and CPU processor reorder the code execution order at their discretion. Optimize the order of instruction execution to improve the performance and execution speed of the program, so that the order of statement execution changes, reordering occurs, but the end result looks the same (single-core).

Problem of 1.2.

In multi-threaded environment (multi-core), the result is not expected because the part of the reorder is switched to another thread before the execution of the reorder is complete. This is the order problem that compiler optimization brings to concurrent programming.

2. Order problem cause – instruction rearrangement

The sequence of instructions that a computer executes after being compiled by a program compiler. Generally, this sequence of instructions produces a definite result. To ensure that each execution has a definite result. But, in general, the CPU and the compiler to enhance the efficiency of program execution, according to certain rules to allow instruction optimization, in some cases, this optimization will bring some logic problems of execution, the main reason is that the code is there between the logical order, in the case of concurrent execution, can produce ambiguity, namely according to the different execution logic, You’ll get different results.

Code examples:

public class Singleton {

    private static Singleton singleton;

    private Singleton(a) {}

    public static Singleton getInstance(a) {
        if (null == singleton) {
            synchronized (Singleton.class) {
                if (null == singleton) {
                    singleton = newSingleton(); }}}returnsingleton; }}Copy the code

For the following code:

singleton = new Singleton();
Copy the code

We thought the order was: 1. Allocate a block of memory 2. Initialize Singleton object 3 on memory. M’s address is then assigned to the instance variable

But it isn’t. Look at JAVA bytecode:

public class com.javashizhan.concurrent.demo.base.Singleton {
  public static com.javashizhan.concurrent.demo.base.Singleton getInstance(a);
    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
}
Copy the code

1. Allocate a block of memory. 2. Assign M’s address to instance 3. Finally, the Singleton object is initialized on memory M.

Due to the order of the instructions, thread A switched before the execution of thread 26 in the case of multi-threading concurrency. At this time, thread B found null == Singleton was not valid and obtained the Singleton. At this time, the singleton was not initialized, so the null pointer exception would be raised.

(3) happens-before rules

Happens-before construres compiler optimization behavior, allowing compiler optimization but requiring compiler optimization to follow the happens-before rule.

In a thread, the previous action is happens-before any subsequent action, in order of procedure. Changes made to a variable in front of the program must be visible to subsequent operations.

2. The volatile variable rule Happens Before any subsequent reads of a volatile variable.

If A happens-before B, B happens-before C, then A happens-before C.

4. Lock rules Happens-before a lock is unlocked.

5. Thread Start rule After main thread A starts child thread B, child thread B can see what the main thread did before it started child thread B.

Thread A waits for thread B to complete (it calls the join method of thread B). When thread B completes (join() returns in thread A), thread A can see the operation of thread B.

A call to the interrupt() method occurs when the code of the interrupted Thread detects that an interrupt has occurred. This can be detected through thread.interrupted ().

The finalization of an object (the completion of constructor execution) occurs first at the start of its Finalize () method.

4. Solve the problem of order

1. Use volatile to modify variables to avoid instruction reordering. Note: Avoiding instruction reordering is not thread-safe. 2. Lock.


<– Read the mark, left like!