Volatile, synchronized, Atomicinteger multi-threaded cumulative 1000 counts difference

Source: Internet
Author: User
Tags volatile

Today, I read an article on the Internet, talking about the volatile feature to use 1000 threads constantly accumulating numbers, each time the cumulative 1, to the final value is not 1000.

The article is a bit misunderstood by others, but in the comments of the article, the author also points out the mistake.

I based on the error of the article and the comments of netizens, summed up some of their own methods and ideas. I hope to discuss with you.

Article Source: http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html

The problem with this article is that 1000 threads may have n (for example, 50) threads not finished, the main thread (the main method) has been executed, so the last count value is not the value we want. Even after 1000 threads have finished executing, the main thread gets the count value, and the data is not necessarily the correct one. Because volatile does not guarantee atomicity, it can only guarantee visibility. See below for analysis.

About volatile:

Java language Specification Description: Each variable has a main memory. To ensure optimal performance, the JVM allows a thread to copy a private copy from main memory, and then reads the variable from the main memory when it is read, and when it exits, synchronizes the modified value to the main memory.

According to the article provided above, it seems to be possible to solve 1000 cumulative calculated values with volatile. But the result is not.

First of all, two concepts: atomicity and visibility

Atomicity, according to my own understanding: The current variable allows only one thread to operate and does not accept multiple threads for access. So each time is the most recent value.

Visibility, according to my own understanding: variable T. A thread modifies the value of the T variable, which is visible to the B thread. But a gets to the value of T plus 1, suddenly hangs, B gets the value is the most recent value, volatile can guarantee that B can get to the T is the most recent value, because A's t+1 is not written into the main memory. There is no problem with this logic.

Back to the above 1000 cumulative problem, the variable count,1000 times cumulative, 1000 threads, volatile can guarantee that each thread read the value of the variable is the latest in memory, this is no problem.

Within these 1000 threads, there will be a scenario like this:

When the NO. 523 thread reads the count value, assuming that the value is 522, the thread adds count to 1, Count is 523, but this time the count value is not written to the main memory, the CPU in some case the No. 523 thread aborts (hangs), so, The NO. 524 thread reads the value from main memory or 522, and when the No. 524 thread writes the value to main memory, the count value is 523, and then the NO. 523 thread starts executing (at this point the No. 523 thread has already added the value of count and the value is 523, except that it is not synchronized to main memory).  Synchronize the Count value to the main memory, this time, the value of count is still 523, the NO. 524 thread accumulated value equals no accumulation. So the final data must not be 1000.

The following code is my personal understanding:


Import Java.util.concurrent.countdownlatch;import Java.util.concurrent.atomic.atomicinteger;public class Counter { public static Atomicinteger count = new Atomicinteger ();//atomic operation public static Countdownlatch latch= new Countdownlatch (1000  );//thread collaboration handles public static volatile int countnum = 0;//volatile can only guarantee visibility and cannot guarantee atomicity public static int synnum = 0;//synchronous processing Compute public static void Inc () {try {thread.sleep (1);} catch (Interruptedexception e) {}countnum++;int c = count.addandget (1); add (); System.out.println (Thread.CurrentThread (). GetName () + "------>" + C);} public static synchronized void Add () {synnum++;} public static void Main (string[] args) {//Start 1000 threads at the same time to perform i++ calculations to see actual results for (int i = 0; i <; i++) {New Thread (new Run Nable () {@Overridepublic void run () {counter.inc (); Latch.countdown ();}}, "thread" + i). Start (); try {latch.await ();} catch (Interruptedexception e) {e.printstacktrace ();} System.out.println (Thread.CurrentThread (). GetName ()); SYSTEM.OUT.PRINTLN ("Run Result: counter.count=" + count.get () + ",,, "+ countnum +",,, "+ Synnum);} 



Count.get () is the value of Atomicinteger;

Count is the value of a variable modified with volatile;

Synnum is a value modified with synchronized;

So, with synchronized and atomicinteger you can guarantee that the data you want, volatile is not guaranteed.


First Run Result:

Main
Operation Result: counter.count=1000,,, 991,,, 1000

Second run Result:

Main
Operation Result: counter.count=1000,,, 998,,, 1000

Third Run Result:

Main
Operation Result: counter.count=1000,,, 993,,, 1000

Visible, even if the use of volatile, there is no guarantee that the data is the data you want, volatile can only guarantee the visibility of your data (access to the latest data, can not guarantee atomicity, plainly, volatile and atomicity do not matter)

To ensure atomicity, the accumulation of data, you can use the Atomicinteger class;

You can also use synchronized to ensure consistency of data.

We welcome the different opinions and views, and discuss and exchange together.

Volatile, synchronized, Atomicinteger multi-threaded cumulative 1000 counts difference

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.