Java volatile keywords

Source: Internet
Author: User

Used in multi-threading, 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)

========================= Split Line 1=================================

Copyright notice: When reproduced, please indicate the original source and author information and this statement in the form of hyperlinks.
Http://aleung.blogbus.com/logs/32090434.html

In the Java memory model, there are main memories, and each thread has its own memory (for example, a register). For performance, a thread keeps a copy of the variable to be accessed in its own memory. This will cause the same variable to appear in a moment when the value in the memory of one thread may be inconsistent with the value in the memory of another thread, or the value in main memory. A variable declared as volatile means that the variable is modified by other threads at any time, so it cannot be cache in the thread memory. The following example shows the effect of volatile:
public class Stoppabletask extends Thread {
Private volatile Boolean pleasestop;
public void Run () {
while (!pleasestop) {
Do some stuff ...
}
}
public void Tellmetostop () {
Pleasestop = true;
}
}
If Pleasestop is not declared volatile, when the thread executes run, it checks its own copy and cannot know in time that other threads have called tellmetostop () to modify the value of Pleasestop. 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. Reference:
    • Http://www.javamex.com/tutorials/synchronization_volatile.shtml
    • Http://www.javamex.com/tutorials/synchronization_volatile_java_5.shtml
    • Http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

========================= Split Line 2=================================

I'm afraid it's easiest to explain the difference between volatile and synchronized. Volatile is a variable modifier, while synchronized acts on a code or method; Look at the following three-sentence get code:

int i1;
int Geti1 () {return i1;}
volatile int i2;
int Geti2 ()
{return i2;}
int i3;
synchronized int Geti3 () {return i3;}



Geti1 () Gets the value i1 stored in the current thread. Multiple threads have multiple copies of I1 variables, and these i1 can differ from each other. In other words, another thread may have changed the I1 value within its thread, and this value can be different from the I1 value in the current thread. In fact, Java has an idea called the "main" memory area, where the variable's current "exact value" is stored. Each thread can have its own copy of the variable, and this variable copy value can be different from the "main" memory area. So there is actually a possibility that the I1 value in the "main" memory area is 1, the I1 value in thread 1 is 2, and the I1 value in thread 2 is 3--that the threads 1 and 2 have changed their respective i1 values, and this change has not yet passed to the "main" memory area or other threads.
Geti2 () Gets the i2 value of the "primary" memory area. Variables modified with volatile do not allow a copy of a variable that differs from the "main" memory area. In other words, a variable has to be synchronized in all threads after a volatile modification; any thread changes its value, and all other threads get the same value immediately. As a matter of course, volatile-modified variables are accessed more often than normal variables because the thread has its own variable copy that is more efficient.
Now that the volatile keyword has implemented data synchronization between threads, what synchronized do? Hehe, there are two different points between them. First, the synchronized obtains and releases the monitor-if two threads use the same object lock, the monitor can force the code block to be executed by only one thread at a time-a well-known fact. However, synchronized also synchronizes memory: in fact, synchronized synchronizes the entire thread's memory in the "primary" memory area. Therefore, the Execute Geti3 () method does the following steps:
1. Thread requests to get an object lock that monitors this object (assuming it is not locked, otherwise the thread waits until the lock is released)
2. Thread memory data is eliminated from the "main" memory area read in (Java virtual function optimization This step ...) [I don't know how to express it back, Khan])
3. code block is executed
4. Any change to the variable can now be safely written to the "main" memory area (although the Geti3 () method does not change the value of the variable)
5. Thread release object lock to monitor this object
So 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.

========================= Split Line 3=================================

The volatile keyword believes that the reader of Java Multithreading is aware of its usefulness. 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. For example, n in the following example is not an atomic level:

Package mythread;

public class Jointhread extends Thread
{
public static volatile int n = 0;
public void Run ()
{
for (int i = 0; i <; i + +)
Try
{
n = n + 1;
Sleep (3); 3 milliseconds delay in order to make the running result more random

}
catch (Exception e)
{
}
}

public static void Main (string[] args) throws Exception
{

Thread threads[] = new thread[100];
for (int i = 0; i < threads.length; i + +)
Build 100 threads
Threads[i] = new Jointhread ();
for (int i = 0; i < threads.length; i + +)
Run the 100 threads you just created
Threads[i].start ();
for (int i = 0; i < threads.length; i + +)
Continue after 100 threads have finished executing
Threads[i].join ();
System.out.println ("n=" + JOINTHREAD.N);
}
}


If the operation on N is atomic level, the result of the final output should be n=1000, and when the area code is executed, many of the output n are less than 1000, which indicates that n=n+1 is not an atomic level operation. Reason is a simple variable declared volatile if the current value is related to the previous value of the variable, then the volatile keyword does not work, meaning that the following expression is not an atomic operation:

n = n + 1;
n + +;


If you want to turn this situation into an atomic operation, you need to use the Synchronized keyword, as the above code can be changed to the following form:

Package mythread;

public class Jointhread extends Thread
{
public static int n = 0;

public static synchronized Void Inc ()
{
n + +;
}
public void Run ()
{
for (int i = 0; i <; i + +)
Try
{
Inc (); n = n + 1 changed to Inc ();
Sleep (3); 3 milliseconds delay in order to make the running result more random

}
catch (Exception e)
{
}
}

public static void Main (string[] args) throws Exception
{

Thread threads[] = new thread[100];
for (int i = 0; i < threads.length; i + +)
Build 100 threads
Threads[i] = new Jointhread ();
for (int i = 0; i < threads.length; i + +)
Run the 100 threads you just created
Threads[i].start ();
for (int i = 0; i < threads.length; i + +)
Continue after 100 threads have finished executing
Threads[i].join ();
System.out.println ("n=" + JOINTHREAD.N);
}
}


The code above changed n=n+1 to Inc (), where the INC method uses the Synchronized keyword for method synchronization. Therefore, it is prudent to use the volatile keyword, not as long as the simple type variable using the volatile modifier, all operations on the variable is the original operation, when the value of the variable is determined by its own last, such as n=n+1, n++, etc., the volatile keyword will be invalidated, 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.

Transfer from http://blog.csdn.net/orzorz/article/details/4319055

Java volatile keywords

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.