Java basics: problems caused by command rescheduling in a concurrent Environment

Source: Internet
Author: User

Java basics: problems caused by command rescheduling in a concurrent Environment
JVM Memory Model-master memory and thread-independent working memory

The Java Memory Model specifies that variables shared by multiple threads are stored in the main memory. Each thread has its own independent working memory, and the thread can only access its own working memory, it cannot access the working memory of other threads. The active memory shared variable is saved in the working memory.CopyThe thread must operate on these shared variables only by operating copies in the working memory. After the operation is completed, the shared variables are synchronized back to the main memory.

How to ensure data integrity of the main memory operated by multiple threads is a challenge. The Java memory model also specifies the protocol for interaction between the working memory and the main memory. First, eight atomic operations are defined:

(1) lock: lock the variables in the main memory to be exclusive to a thread.

(2) unclock: unlock lock. Other threads can access this variable.

(3) read: read the variable values in the main memory to the working memory.

(4) load: Save the read value to the variable copy in the working memory.

(5) use: the code execution engine that passes the value to the thread.

(6) assign: assign the value returned by execution engine processing to the variable copy.

(7) store: store the value of the variable copy to the primary memory.

(8) write: write the value stored in the store to the shared variable in the primary memory.

1. Concept of memory visibility 1.1

Based on the above Java memory model, we will notice that every thread will operate on shared variables in its working memory after obtaining the lock, after the operation is complete, the copy in the working memory will be written back to the primary memory, and before other threads synchronize the variables from the primary memory back to their working memory, the changes to the shared variables are invisible to them.

1.2 problems caused by memory visibility

Many times we need a thread to change the shared variable. Other threads also need to know the change immediately. What should we do? For example, in the following scenario, there is a global state variable open:

Boolean open = true;

This variable is used to describe the status of opening and closing A resource. true indicates opening and false indicates closing. If there is A thread A, after performing some operations, change open to false:

// Thread

Resource. close ();

Open = false;

Thread B is always concerned about the open state. When open is true, some operations are performed by accessing resources:

// Thread B

While (open ){

DoSomethingWithResource (resource );

}

When A closes the resource, the open variable is invisible to thread B. If the changes to the open variable are not synchronized to the working memory of thread B, then thread B will use a closed resource for some operations, thus generating an error.

1.3 volatile keywords

Therefore, the preceding scenario requires a thread to change the open state, and other threads can be immediately visible. Java provides the volatile keyword for this purpose, when declaring the open variable, you can add the volatile keyword to ensure the memory visibility of open. That is, the change of open is immediately visible to all threads.

Volatile ensures visibility inRefresh Every time you access the variable.Therefore, each access is the latest version in the main memory. So one of the functions of the volatile keyword isEnsures real-time visibility of variable modifications.

2. Command rescheduling 2.1 concepts

Command Re-sorting is implemented by JVM to optimize commands and improve program running efficiency. Command Re-sorting includes compiler re-sorting and runtime re-sorting. The JVM specification specifies that the command re-sorting can be performed without affecting the execution results of a Single-threaded program.

2.2 problems caused by command re-arrangement Example 1: simple command re-arrangement

Suppose there are two shared variables a and B:

Private int;

Private int B;

There are two statements in thread A to assign values to the two shared variables:

A = 1;

B = 2;

Suppose that thread A is performing a copy operation on thread A and finds that the variable has been locked by other threads in the main memory. What should thread A do at this time? Waiting to release the lock? No, it is a waste of time. It will try to assign values to B. B is not occupied at this time, so it will assign values to B first, and then assign values to, then the execution order is changed:

B = 2;

A = 1;

Example 2: Line B errors caused by A thread instruction shuffling

For the same thread, such changes will not affect the logic, but in the case of multithreading, re-sorting of commands will cause problems. Let's look at the following scenario:

In thread:

Context = loadContext ();

Inited = true;

 

In thread B:

While (! Inited) {// determines whether to use the context Variable Based on the inited variable modified in thread.

Sleep (100 );

}

DoSomethingwithconfig (context );

Assume that commands are reordered in thread:

Inited = true;

Context = loadContext ();

In B, a context that has not been initialized or has not been initialized is likely to be obtained, causing a program error.

Example 3: The Singleton mode becomes invalid due to command re-arrangement

We all know a classic Singleton mode of lazy loading:

Public class Singleton {

Private static Singleton instance = null;

Private Singleton (){}

Public static Singleton getInstance (){

If (instance = null ){

Synchronzied (Singleton. class ){

If (instance = null ){

Instance = new Singleton ();

}

}

}

Return instance;

}

}

A simple assignment statement: instance = new Singleton (); in fact, the JVM has been converted into multiple commands:

Memory = allocate (); // 1: allocate the memory space of the object

CtorInstance (memory); // 2: initialization object

Instance = memory; // 3: Set the instance to point to the allocated memory address.

However, after being reordered, it is as follows:

Memory = allocate (); // 1: allocate the memory space of the object

Instance = memory; // 3: Set the instance to point to the allocated memory address. At this time, the object has not been initialized.

CtorInstance (memory); // 2: initialization object

As you can see, after the command re-arrangement, the instance points to the allocated memory placed in front, and the memory initialization is placed behind, before thread A initializes the memory, although thread B does not enter the synchronization code block, the judgment before synchronizing the code block will find that the instance is not empty. In this case, when thread B obtains the instance Object for use, an error may occur.

2.3 volatile keywords

In addition to the volatile keyword mentioned in memory visibility, variable modification visibility can also be ensured:After JDK1.5, you can use the volatile variable to disable command re-sorting.

After the variables in example 2 and Example 3 are modified with the keyword volatile, the JVM will organize the command re-arrangement on the relevant code, so that the commands can be executed in the specified order.

Summary

Compared with the synchronized block code lock, volatile should provide a lightweight lock for shared variables, when we use shared variables to communicate among multiple threads, we need to consider using volatile to modify the shared variables.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.