About atomic operations and volatile keywords in Java

Source: Internet
Author: User
Tags modifier volatile

Original post: http://rwl6813021.javaeye.com/blog/349169

When studying Threadpoolexecutor, it was found that the volatile variables were used extensively. Do not know why, so did a search, research: which borrowed a lot of online data. Before understanding the role of volatile variables, we need to understand some concepts:

what is atomic operation.
So-called atomic operation, is "an interruptible or a series of operations", in the case of confirming an operation to be an atom, we can avoid to protect this operation on the periphery plus expensive lock, even with the help of atomic operation, we can implement mutual exclusion lock. Many operating systems provide +--valued atomic operating versions for int types, such as NT provides InterlockedExchange APIs, Linux/unix also provides functions such as Atomic_set.

about atomic sex in Java.
Atomicity can be applied to "simple operations" above all basic types except long and double. Operations such as the basic type variables, which are read and written out of a long double, guarantee that they will be manipulated as non-splitting (atomic) operations. Because of the JVM version and other problems, many other operations are not easy to say, for example, + + operations in C + + is atomic operation, but in Java is not easy to say. In addition, Java provides atomic classes such as Atomicinteger. Then the use of atomicity to control concurrency is more troublesome, but also prone to problems.

What is the volatile principle?
Java volatile keyword literal is "unstable, change" meaning
The difference between using volatile and not using volatile is that the JVM memory main and the thread working memory are synchronized. The volatile ensures that the variables are consistent between thread working memory and main memory.
In fact, tell the processor, do not put me into working memory, please directly in main memory operation of me.

Next is the test: (through testing to better detect and analyze problems)
Several types of reshaping variables are stated, 100 threads are opened and the variables are added + +, and the results vary widely:
>>execute End:
>>atomic:100000
>>vinteger:38790
>>integer:68749
>>source i:99205
>>source vi:99286
That is to say, other than atomic, everything else is wrong.

We have some questions to explain.

1: Why the wrong data is generated.
Multithreading, because for multithreading at the same time the operation of an integer variable in the case of large concurrent operation can not be synchronized, and Atom provides a lot of solutions for such thread security problems, thus resolving the problem of simultaneous read and write operations.


2: Why the synchronization problem is caused.
Java multithreading in the operation of the variable, in fact, each line Cheng a separate copy of the I value (isolated memory area), but the declared I value is in the main memory area, and when the I value is modified, the thread copies the I value from its own memory area block into the main memory area. So it is possible that each thread will get a different I value, resulting in a synchronization problem.


3: Why After you use volatile to decorate an integer variable, you still can't.
Because volatile only solves the problem of storage, that is, the I value is only kept in a single memory area, but i++ this operation involves acquiring I, modifying I, storing I (i=i+1), where the volatile only solves the problem of storing I, as for acquiring and modifying the I value, is not synchronized.


4: Since you can't sync, why use the volatile modifier.
One of the main reasons is convenience, because you can simply add a modifier without having to do object lock and unlock such cumbersome operations. But I do not recommend the use of this mechanism, because it is more prone to problems (dirty data), but also can not guarantee synchronization.


5: How to solve such a problem in the end.
The first: Using synchronous synchronized solution, which solves the problem, but also reduces the performance of the system.
The second: the use of atomic data atomic variables, this is the beginning of the JDK1.5 for the atomic solution, this solution is also a better solution now.


The realization principle of 6:atomic.
First, the variables in the atomic are declared for volatile variables, so that the variables are stored and read consistently, all from the same block of memory, and then atomic provides a getandincrement method that encapsulates the variable + + operation. The Compareandset method is provided to complete the lock and unlock operation of a single variable, and a unsafe object is used in the method, and it is not yet known how the unsafe works (it does not appear to disclose the source code). Atomic Although solve the problem of synchronization, but the performance of the above still will have some loss, but the impact is small, online for this aspect of the test, about 50million operation is 250ms:850ms, for most high-performance applications, should still be enough.

package qflag.ucstar.test.thread;

  

Import Java.util.concurrent.atomic.AtomicInteger;

/**
* Test for Atomicity synchronization
* @author Polarbear 2009-3-14
*
*/
public class Testatomic {

public static Atomicinteger astom_i = new Atomicinteger ();

public static volatile Integer V_integer_i = 0;

public static volatile int v_i = 0;

public static Integer Integer_i = 0;

public static int i = 0;

public static int endthread = 0;

public static void Main (string[] args) {
New Testatomic (). Testatomic ();
}

public void Testatomic () {

for (int i=0; i<100; i++) {
New Thread (New Integertestthread ()). Start ();
}

try {
for (;;) {
Thread.Sleep (500);
if (testatomic.endthread = = 100) {
System.out.println (">>execute End:");
System.out.println (">>atomic:/T" +testatomic.astom_i);
System.out.println (">>vinteger:/T" +testatomic.v_integer_i);
System.out.println (">>integer:/T" +testatomic.integer_i);
System.out.println (">>source I:/t" +TESTATOMIC.I);
System.out.println (">>source Vi:/T" +testatomic.v_i);
Break
}
}

catch (Exception e) {
E.printstacktrace ();
}
}

}
Class Integertestthread implements Runnable {
public void Run () {
int x = 0;
while (x<1000) {
TestAtomic.astom_i.incrementAndGet ();
testatomic.v_integer_i++;
testatomic.integer_i++;
testatomic.i++;
testatomic.v_i++;
x + +;
}
++testatomic.endthread; It seems to be invincible. Is it atomic?
}
}

-----------------------------------------xx-----------------------------------xx------------------------------------- ----------

I continue to add:

Other variables are ignored except for the testatomic.endthread. See comments for a specific explanation.



Import Java.util.concurrent.atomic.AtomicInteger;
Import java.io.*;

/**
* Test for Atomicity synchronization
* @author PYc 2009-3-29
*
*/
public class Testatomic {
public static final int n=10;
public static final int m=10000;
public static int perfect_result=m*n;
public static int endthread = 0;

Private PrintWriter out;//Input the information to the text "OUT.txt" because the console buffer may not be enough.

Public testatomic () throws IOException
{
Out =new PrintWriter (
New BufferedWriter (
New FileWriter ("OUT.txt"));
}

public static void Main (string[] args) {
try{
New Testatomic (). Testatomic ();
}catch (Exception e) {
System.out.println (E.getmessage ());
}
System.out.println ("ok./nstatistical:");
System.out.println ("Covered by" + (Perfect_result-endthread) + "times.");
}

public void Testatomic () {
Thread[] Td=new Thread[n];
for (int i=0; i<n; i++) {
Td[i]=new Thread (New Integertestthread (i+1));
}
for (int i=0; i<n; i++) {
Td[i].start ();
Out.println ((i+1) + "go."); Here if the run () method code is small, complete completion information can be observed immediately.
}
try {
Long temp=0; The last Endtread value was stored.
int count=1000; If the temp value is more than 1000 repetitions, you can think of the end of the program.
for (;;) {
Thread.Sleep (1); It is possible for the main thread to run too fast to adjust the frequency of the sample.
if (Testatomic.endthread = = Perfect_result) {
Out.println ("==============/r/nperfect!/r/n=============="); Perfect match.
Break
}
if (temp==testatomic.endthread) {
Out.println ("equal!!"); /There may be duplicates at the end of all threads, or it may be that the main thread is sampling too quickly.
count--;//countdown ...
}
else {
temp=testatomic.endthread;//assigns a new value to temp.
count=1000;//Reset the countdown.
}
Out.println ("Endthread =" +testatomic.endthread); there is a chance to observe that the current Endthread value is less than the previous one.
This is the key.
if (count<=0)
{
Out.println ("/r/ni ' ll be crazy if I") to that once again!/r/nfailed, OMG. +_+");
Break
}
}
Out.close ();
}catch (Exception e) {
E.printstacktrace ();
}
}

Class Integertestthread implements Runnable {
private int id;
Public integertestthread (int i) {
This.id=i;
}
public void Run () {
int i=m;//fully guarantee thread overlap run
while (i>0) {
try{
Thread.Sleep ((int) (10*math.random ()))//Set the sleep time so that threads overlap as much as possible.
}catch (Exception e) {
++testatomic.endthread;//tests the "atomic" nature of the statement. In fact, after the experiment, we know that
++i,i++, i=i+1 is no guarantee of atomicity.
We can learn from the final Endthread value is not equal to m*n.
i--;
}
Out.println ("************/r/n" +id+ "has completed!/r/n************/r/n");
}
}
}

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.