Java Theory and Practice: Correct Use of Volatile variables (1)

Source: Internet
Author: User

Java Theory and Practice: Correct Use of Volatile variables (1)

 

The volatile variable in Java can be seen as a "to a lesser extent"synchronized"; AndsynchronizedCompared with the block, the volatile variable requires less encoding and less runtime overhead. However, the only function it can implement issynchronized. This article introduces several effective modes for Using volatile variables, and emphasizes the situations where volatile variables are not suitable for use.

The lock provides two main features:Mutex mutual exclusion)AndVisibility). Mutex allows only one thread to hold a specific lock at a time. Therefore, you can use this feature to implement a coordinated access protocol for shared data. In this way, only one thread can use the shared data at a time. Visibility is more complex. It must ensure that changes made to the shared data before the lock is released are visible to another thread that subsequently acquires the lock-if this visibility guarantee is not provided by the synchronization mechanism, the shared variables seen by the thread may be values before modification or inconsistent values, which will cause many serious problems.

Volatile variable

The Volatile variable hassynchronizedBut not atomic. This means that the thread can automatically discover the latest value of the volatile variable. Volatile variables can be used to provide thread security, but can only be used in a very limited set of Use Cases: There is no constraint between multiple variables or between the current value of a variable and the modified value of a variable. Therefore, using volatile alone is not enough to implement counters, mutex locks, or any non-variant Invariants related to multiple variables), such as "start <= end ").

For simplicity or scalability, you may prefer to use volatile variables instead of locks. Some Usage of idiom is easier to code and read when volatile variables are used instead of locks. In addition, the volatile variable does not cause thread blocking like a lock, so it rarely causes scalability problems. In some cases, if the read operation is far greater than the write operation, the volatile variable can also provide performance advantages over the lock.

Conditions for correct use of volatile Variables

You can only replace the lock with the volatile variable in a limited number of cases. To enable the volatile variable to provide ideal thread security, the following conditions must be met simultaneously:

  • Write operations on variables do not depend on the current value.
  • This variable is not included in the variant with other variables.

In fact, these conditions indicate that the valid values that can be written into the volatile variable are independent of the State of any program, including the current state of the variable.

The limitation of the first condition makes the volatile variable not used as a thread security counter. Although incremental operationsx++) It looks like a separate operation. In fact, it is a combination of read-Modify-write operation sequences and must be executed in an atomic manner, while volatile cannot provide the required atomic features. To achieve the correct operation, you needxThe value remains unchanged during the operation, while the volatile variable cannot. However, if you adjust the value to write data only from a single thread, you can ignore the first condition .)

Most programming scenarios conflict with one of these two conditions, making the volatile variable notsynchronizedThis method is applicable to thread security. Listing 1 shows a non-thread-safe value range class. It contains a non-variant-the lower bound is always less than or equal to the upper bound.

List 1. Non-thread-safe value range class

@NotThreadSafe public class NumberRange {    private int lower, upper;    public int getLower() { return lower; }    public int getUpper() { return upper; }    public void setLower(int value) {         if (value > upper)             throw new IllegalArgumentException(...);        lower = value;    }    public void setUpper(int value) {         if (value < lower)             throw new IllegalArgumentException(...);        upper = value;    }}

This method limits the range of state variables, solowerThe definition of the upper field as the volatile type does not fully implement the thread security of the class; therefore, synchronization still needs to be used. Otherwise, if two threads use inconsistent values for execution at the same timesetLowerAndsetUpperOtherwise, the range will be in an inconsistent state. For example, if the initial status is(0, 5), Thread A calls at the same timesetLower(4)And thread B callssetUpper(3)Obviously, the values of the two operations do not meet the conditions, so both threads will pass the check to protect the variant, so that the final range value is(4, 3)-- An invalid value. For other operations on the scope, we needsetLower()AndsetUpper()Operation atomicity -- defining a field as the volatile type cannot achieve this goal.

Performance Considerations

The main reason for using the volatile variable is its simplicity: in some cases, using the volatile variable is much easier than using the corresponding lock. The secondary reason for using the volatile variable is its performance: in some cases, the volatile variable synchronization mechanism has better performance than the lock.

It is difficult to make accurate and comprehensive comments, such as "X is always faster than Y", especially for internal JVM operations. For example, in some cases, the VM may be able to completely delete the lock mechanism, which makes it difficult for us to abstract and comparevolatileAndsynchronized.) That is to say, in most of the current processor architectures, the volatile read operation overhead is very low-almost the same as the non-volatile read operation. Volatile write operations have more overhead than non-volatile write operations, because to ensure visibility, the Memory must be defined to define the Memory Fence). Even so, the total cost of volatile is still lower than the lock acquisition.

Volatile operations do not cause congestion like locks. Therefore, volatile provides some scalable features that are better than locks when volatile can be safely used. If the number of read operations far exceeds the write operation, compared with the lock, the volatile variable can usually reduce the performance overhead of synchronization.


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.