1. What are the categories of variables

    Global variables = properties (static, non-static) Local variables = local variables, parameters

  2. Multiple threads share data

    Global variables: static variables or shared objects

  3. The issue of variable visibility in concurrency is whether concurrent threads can see the latest value of a shared variable

    (1) Why is it invisible?

    (2) How can it be seen

    The thread body is wrapped using the synchroized keyword

    Use the volatile keyword to decorate shared variables

  4. JAVA memory model and operation specification

    (1) Shared variables must be stored in main memory.

    (2) Threads have their own working memory and can only operate on their own working memory.

    (3) To operate the shared variable, the thread needs to read the variable value from the main memory to the working memory, and then synchronize the change from the working memory to the main memory.

(1) There are multiple copies of data, resulting in inaccurate data when multiple threads simultaneously read and write the same variable. Thread-safety issues.

(2) So use thread synchronization or locking.

  1. The variable changes in thread 1, and you can see its latest value in thread 2

    (1) After thread 1 changes A, it must immediately synchronize back to main memory

    (2) Thread 2 needs to read from main memory to working memory again before using A

  2. JAVA Memory model – Synchronous interaction protocol, which specifies eight atomic operations

    (1) Lock Locks variables in main memory, making them exclusive to one thread.

    (2) UNLOCK unlocks a variable in main memory, allowing other threads to access the variable.

    (3) Read (read) on the main memory variable, the main memory variable value read to the working memory (read from the main memory to the register).

    (4) Load acts on working memory variables, saving the value read to a copy of the variables in working memory (register variables are loaded into working memory).

    The working memory variable is used to pass its value to the thread’s code execution engine.

    Assign applies to the working memory variable, which reassigns the value returned by the execution engine to the copy of the variable.

    (7) Store acts on a working memory variable, transferring the value of a copy of the variable to main memory (read from working memory to registers).

    (8) Write on main memory variable, writes the value passed by store to the shared variable of main memory (register variable is written to main memory).

    Note: any combination of operations is not atomic.

    (1) Copy a variable from main memory to working memory, perform read and load operations sequentially; To synchronize variables from working memory back to main memory, perform stroe and write operations in sequence. Only sequential execution is required, not necessarily sequential (i.e., atomic operations).

    (2) Assign operation, must be synchronized back to main memory. Do not assign to the main memory. (It is not necessary to immediately synchronize to the main memory after being assigned.)

  3. Final synchronized volatile ensures variable visibility in concurrency

  4. Synchronized semantic specification (both visibility and thread-safety)

    (1) Before entering the synchronization block, clear the shared variables in the working memory and reload them from the main memory.

    (2) Before unlocking, you must synchronize the modified shared variables back to the main memory.

    (3) At the core, synchronized has a locking mechanism, and only the thread that obtains the lock can operate the shared resource. (Pessimistic lock)

  1. Volatile semantic specification (ensuring visibility and consistency between working memory variables and main memory variables)

    (1) When volatile variables are used, they must be reloaded from main memory, and read and load are contiguous.

    (2) After volatile variables are modified, they must be immediately synchronized back to main memory, and store and write are contiguous.

  2. Is Volatile thread-safe? (Atomicity cannot be guaranteed)

    (1) No, because it has no locking mechanism, threads can concurrently operate shared resources.

  1. Volatile is simpler to use and performs slightly better than synchronized.
  2. Volatile can also be used to restrict reordering of local code instructions

(1) Some code of thread A and thread B

Thread A content = initContent(); isInit =true;
Copy the code
Thread Bwhile(isinit) {
        content.oper();
    }
Copy the code

(2) After the JVM optimization instructions are reordered

Thread A(because two lines of code, no matter) isInit = true; content = initContent();Copy the code

(3) When two threads execute concurrently, null exceptions may occur in the content of thread B.

  1. The scope of use of volatile

    (1) Only member variables (static and non-static) can be modified. Shared variables can only be global variables to ensure visibility.

    (2) Multi-threaded concurrency, only need to use.

  2. The use of the volatile keyword in the singleton pattern