The atomic variables of Java concurrent programming

Source: Internet
Author: User
Tags cas volatile

One of the main characteristics of atomic variables is that all operations are atomic, and the Synchronized keyword can also be used to manipulate the atomic variables. Just the cost of synchronized is relatively high, you need to acquire the lock object, release the lock object, and if you cannot get to the lock, you also need to block waiting on the blocking queue. It is recommended that you use atomic variables only to resolve atomic operations on variables. The introduction of atomic variables mainly involves the following:

    • Basic concepts of atomic variables

    • Understanding the basic use of atomic variables through Atomicinteger

    • Understanding the fundamentals of atomic variables by Atomicinteger

    • Basic use of Atomicreference

    • Using Fieldupdater to manipulate field properties for non-atomic variables

    • The solution to the classical ABA problem

First, the basic concept of atomic variables
Atomic variables ensure that all operations of the variable are atomic and do not cause the problem of dirty data reading because of simultaneous access to multiple threads. Let's take a look at the Synchronized keyword to guarantee the variable atomicity code:

For a simple count++ operation, the thread object first needs to acquire an object lock to the Counter class instance, then completes the self-increment operation and finally releases the object lock. The entire process, whether acquiring a lock or releasing a lock, is quite cost-free, and once you can't get to the lock, you need to block the current thread and so on.

In this case, we can declare the count variable as an atomic variable, so the increment of count can be done atomically, and there is no reading of dirty data. Java provides us with the following kinds of atomic types:

    • Atomicinteger and Atomicintegerarray: Based on integer type

    • Atomicboolean: Based on the Boolean type

    • Atomiclong and Atomiclongarray: based on long type

    • Atomicreference and Atomicreferencearray: based on reference type

In the remainder of this article, we will mainly introduce the two types of Atomicinteger and atomicreference, the use of Atomicboolean and atomiclong, and the principle of internal implementation almost like Atomicinteger.

Second, the basic use of Atomicinteger

First look at its two constructors:

As you can see, when we construct the Atomicinteger atom variable through a constructor, if we specify an int parameter, the value of the atomic variable is assigned, otherwise it is the default value 0.

There are also methods to get and set this value:

Of course, these two methods are not atomic, so they are rarely used, and the following methods of atomic manipulation are relatively frequently used, as for their specific implementation, we will be in the next section of this article to do a simple study.

Here we implement an example of a counter, previously implemented using synchronized, and now we use atomic variables to implement the problem again.

It is clear that the use of atomic variables is much simpler and more efficient than using synchronized.

Three, the internal basic principle of Atomicinteger

Atomicinteger implementation principle is a bit like our packaging class, the internal main operation is the Value field, this field is saved is the value of the atomic variable. The value field is defined as follows:

private volatile int value;

The Value field is first modified by volatile, that is, there is no memory visibility issue. Because of the almost similar code that implements atomic operations internally, we mainly learn the implementation of the Incrementandget method.

Before exposing the implementation principle of this method, let's look at another method:

Compareandset method is also called the CAs, the method calls Unsave a Compareandswapint method, this method is native, we do not see the source code, But we need to know the goal of this method: to compare whether the value of the current atomic variable is equal to expect, and if so, to change it to update and return True, otherwise return false directly. Of course, the operation itself is atomic, the lower level of implementation.

Before jdk1.7, our incrementandget approach was implemented like this:

The method body is a dead loop, current gets to the value in the present atomic variable, because value is modified volatile, so there is no memory visibility problem, the data must be up-to-date. Then current adds a value to next, calls our CAs atomic operation to determine if value has been modified by another thread, if it is the original value, then assign the value of next to value and return to next, otherwise retrieve the value of the present value, again to judge, Until the operation is complete.

A very central idea of the Incrementandget method is to take a look at the value of values before adding one, and then to look at the actual addition, and if the discovery changes, do not manipulate the data, otherwise value plus one.

But after the jdk1.8, some optimizations were made, but finally the Compareandswapint method was called. But the basic idea has not changed.

Iv. Basic use of atomicreference
For some of these reference types, such as custom classes or strings, Java and the package also provide interface support for atomic variables. Atomicreference is implemented internally using generics.

Some of the other atomic methods are as follows:

Some of the atomicreference are less self-decreasing, but the modifications to value are still atomic.

V. Using Fieldupdater to manipulate non-atomic Variable field properties
Fieldupdater allows us to use reflection to manipulate fields directly atomically, without having to set the field as an atomic variable. For example:

Then we create 100 threads that randomly call the Addcount method of the same counter object, no matter how many times it runs, and the result is 100. The atomic operation implemented in this way does not need to be packaged as an atomic variable for the manipulated variable, but it can manipulate its value directly in an atomic manner.

Six, the classic ABA problem
Our atomic variables all depend on a core approach, which is CAs. The core idea of this method is to get the current value of the variable before changing the value of the variable, and then get the value of the variable again when it is actually changed, or change it if it is not modified, otherwise loop until the change is complete. If a thread wants to modify the variable count to get a value of count before the actual operation, a thread will change the count value to B, a thread gets the value of count to B and the count is modified to a, At this point the first thread has no idea that the value of count has been modified twice, although the value is still a, but the data is actually dirty.

This is the typical ABA problem, and one solution is to record the current timestamp for each operation of count, so that we not only look at the most recent value of count, but also record the timestamp of the count, in the actual operation, until we have the atomic operation count. The modify operation is completed only if the value of count and the timestamp have not been changed.

The CAs method of atomicstampedreference requires four parameters to be passed in, and the internal of the method compares both count and stamp, and CAS modifies the value of count only if neither of these values has changed.

Above we introduce the most basic content of the atom variable, and finally we compare the difference between the atom variable and the synchronized keyword.

From the thinking mode, the atomic variable represents an optimistic non-blocking thinking, it assumes that no one else will be working with me at the same time a variable, so before actually modifying the value of the variable will not lock the variable, but when the variable is modified by using CAS, once the conflict is found, continue to try until the variable is successfully modified.

The Synchronized keyword is a pessimistic blocking thinking that everyone will be working with me at the same time to manipulate a variable, so lock the variable before it will be manipulated, and then continue to manipulate the variable.

The atomic variables of Java concurrent programming

Related Article

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.