Whether volatile is atomic/thread-synchronous

Source: Internet
Author: User
Tags volatile

In Java thread concurrency processing, there is a very big confusion about the use of a keyword volatile, for the use of this keyword, in the multi-threaded concurrent processing can be all right.

The Java language is multi-threaded, in order to solve the problem of thread concurrency, the synchronization block synchronized and the volatile keyword mechanism are introduced inside the language. synchronizedSynchronization Block Everyone is more familiar with the Synchronized keyword to achieve, all plus synchronized and block statements, in multi-threaded access, at the same time only one thread can be usedsynchronized a modified method or block of code.  volatilewith volatile modifiers, the thread reads the most recent value of the variable every time the variable is used. Volatile is easily misused and used for atomic operations. Here is an example, we implement a counter, each time the thread starts, the Counter Inc method is called, the counter is added one:
 Public classTestvolatile {/** Execution Environment--JDK version: jdk1.6.0_31, Memory: 3G cpu:x86 2.4G*/     Public Static intCount = 0;  Public Static voidInc () {//The delay is 1 milliseconds, making the result obvious        Try{Thread.Sleep (1); } Catch(Interruptedexception e) {} count++; }     Public Static voidMain (string[] args) {//Start 1000 threads at the same time to perform i++ calculations to see the actual results         for(inti = 0; i < 1000; i++) {            NewThread (NewRunnable () { Public voidrun () {testvolatile.inc ();        }}). Start (); }        //there may be different values for each run, which may beSYSTEM.OUT.PRINTLN ("Run Result: testvolatile.count=" +testvolatile.count); }}//running Result: counter.count=995
The results of The actual operation may not be the same each time, the result of the machine is: Running results: counter.count=995, you can see, in the Multi-threaded environment, Counter.count did not expect the result is 1000. Many people think that this is a multi-threaded concurrency problem, just need to add the variable count before the volatile to avoid this problem, we have to modify the code to see if the results are not in line with our expectations.
 Public classTestvolatile { Public volatile Static intCount = 0;  Public Static voidInc () {//The delay is 1 milliseconds, making the result obvious        Try{Thread.Sleep (1); } Catch(Interruptedexception e) {} count++; }     Public Static voidMain (string[] args) {//Start 1000 threads at the same time to perform i++ calculations to see the actual results         for(inti = 0; i < 1000; i++) {            NewThread (NewRunnable () { Public voidrun () {testvolatile.inc ();        }}). Start (); }        //there may be different values for each run, which may beSYSTEM.OUT.PRINTLN ("Run Result: testvolatile.count=" +testvolatile.count); }}//running Result: counter.count=992
  The result of the operation is still not what we expected 1000, below we analyze the reason:in the Java garbage collection article, the allocation of memory at runtime of the JVM is described. One of the memory areas is the JVM virtual machine stack, each thread runs with a line stacks, and the line stacks saves the thread runtime variable value information. When a thread accesses an object, the value of the variable that corresponds to the heap memory is first found by the object's reference, and then the heap memorythe specific value of the variable is load into the thread's local memory, a copy of the variable is created, and then the thread is no longer related to the object in the heap memory variable value, but directly modifies the value of the replica variable.at some point after the modification (before the thread exits), the value of the thread variable copy is automatically written back to the object in the heap variable. This changes the value of the object in the heap. Here is a picturedescribe these interactions:              

Read and load: Copies the variable from main memory to the current working RAM.
Use and assign: Executes the code, changing the shared variable value.
Store and write: Flushes the contents of main memory with work-in data.

Where use and assign can appear multiple times.

However, these operations are not atomic, that is, after the read load, if the main memory count variable is modified, the value in the thread's working memory will not change because it has been loaded, so there will be multithreading concurrency problems.

The volatile keyword is used in multi-threaded, synchronous variables. thread to improve efficiency, a member variable (such as a) copy a copy (such as b), the thread of access to a actually access is B. Synchronization of A and B occurs only in certain actions. Thus there is a and B inconsistency. Volatile is used to avoid this situation. Volatile tells the JVM that the variable it modifies does not keep the copy and accesses the main memory directly (that is, a above).

Volatile is generally not a substitute for sychronized, because volatile does not guarantee the atomicity of the operation, even if only i++, is actually composed of multiple atomic operations: Read I; Inc; Write I, if multiple threads execute i++,volatile at the same time can only guarantee that I is the same piece of memory, but it is still possible to write dirty data. If you add atomic wrapper classes with Java 5, you do not need sychronized for operations such as their increase.

Volatile is a variable modifier, while synchronized acts on a piece of code or method. Volatile is simply synchronizing the value of a variable between the thread memory and the "primary" memory, while the synchronized synchronizes the values of all variables by locking and unlocking a monitor. Obviously synchronized consumes more resources than volatile.

The volatile keyword is used to declare simple type variables such as int, float, and Boolean data types. If these simple data types are declared volatile, the operation on them becomes atomic level. But there is a certain limit to this.

When the value of a variable is determined by its own previous decision, such as N=n+1, n++, and so on, it is not an atomic operation. The action on a variable is atomic level only if its value is independent of its previous value, such as n = m + 1, which is the original level. So when using volatile key must be cautious, if you are not sure, you can use synchronized instead of volatile.

Volatile is atomic/thread-synchronized

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.