Use Volatile variable or atomic variable

Source: Internet
Author: User

  • Volatile variable

In Java, the volatile variable provides a lightweight synchronization mechanism. The volatile variable is used to notify other threads of variable update operations, the volatile variable is not cached in a register or invisible to other processors. Therefore, the latest written value is always returned when the volatile variable is read. The volatile variable is usually used to indicate a status identifier.


  • Atomic variable:

Atomic variables are "more powerful volatile" variables. From the implementation point of view, the value attribute of each atomic variable class is a volatile variable, so the volatile variables also have the characteristics of atomic variables. At the same time, atomic variables provide atomic operations for reading, modifying, and writing, which are more powerful and more suitable for general concurrent scenarios.


Since atomic variables are more powerful, is it necessary to use volatile variables? When should I select the volatile variable and the atomic variable? Of course, this option is only available in the scenario of multi-thread concurrency. The purpose of multi-thread concurrency is generally to increase throughput and reduce latency responses. So let's take a look at the testing code and running results first!

Import java. util. concurrent. countDownLatch; import java. util. concurrent. atomic. atomicInteger; public class TestVolatile {private static int CALC_TIME = 1000; private static final int THREAD_NUM = 100; private AtomicInteger ai; private int I; private volatile int vi; public TestVolatile () {ai = new AtomicInteger (0); I = 0; vi = 0;} public static void main (String [] args) throws InterruptedException {System. out. println ("Calculation Times:" + CALC_TIME + "--------------------"); test (); CALC_TIME = 10000; System. out. println ("Calculation Times:" + CALC_TIME + "--------------------"); test (); CALC_TIME = 100000; System. out. println ("Calculation Times:" + CALC_TIME + "--------------------"); test (); CALC_TIME = 1000000; System. out. println ("Calculation Times:" + CALC_TIME + "----------------------"); test ();} private static void test () throws InterruptedException {testAi (); testI (); testVi ();} private static void testAi () throws writable {TestVolatile testVolatile = new TestVolatile (); CountDownLatch begSignal = new round (1); CountDownLatch endSignal = new CountDownLatch (THREAD_NUM ); for (int I = 0; I <THREAD_NUM; I ++) {new Thread (testVolatile. new WorkerAI (begSignal, endSignal )). start ();} long startTime = System. currentTimeMillis (); begSignal. countDown (); endSignal. await (); long endTime = System. currentTimeMillis (); System. out. println ("Total time consumed by atomic increment:" + (endTime-startTime);} private static void testI () throws InterruptedException {TestVolatile testVolatile = new TestVolatile (); countDownLatch begSignal = new CountDownLatch (1); CountDownLatch endSignal = new CountDownLatch (THREAD_NUM); for (int I = 0; I <THREAD_NUM; I ++) {new Thread (testVolatile. new WorkerI (begSignal, endSignal )). start ();} long startTime = System. currentTimeMillis (); begSignal. countDown (); endSignal. await (); long endTime = System. currentTimeMillis (); System. out. println ("Total time consumed by synchronized increment:" + (endTime-startTime);} private static void testVi () throws InterruptedException {TestVolatile testVolatile = new TestVolatile (); countDownLatch begSignal = new CountDownLatch (1); CountDownLatch endSignal = new CountDownLatch (THREAD_NUM); for (int I = 0; I <THREAD_NUM; I ++) {new Thread (testVolatile. new WorkerVI (begSignal, endSignal )). start ();} long startTime = System. currentTimeMillis (); begSignal. countDown (); endSignal. await (); long endTime = System. currentTimeMillis (); System. out. println ("Total time consumed by volatile increment:" + (endTime-startTime);} public void incrAi () {ai. getAndIncrement ();} public synchronized void incrI () {I ++;}/*** this function is not thread-safe and may produce incorrect results, this is only to test the efficiency of reading volatile variables */public void incrVi () {vi ++;} class WorkerAI implements Runnable {private CountDownLatch beginSignal; private CountDownLatch endSignal; public WorkerAI (CountDownLatch begin, CountDownLatch end) {this. beginSignal = begin; this. endSignal = end ;}@ Override public void run () {try {beginSignal. await ();} catch (InterruptedException e) {e. printStackTrace () ;}for (int j = 0; j <CALC_TIME; j ++) {incrAi () ;} endSignal. countDown () ;}} class WorkerI implements Runnable {private CountDownLatch beginSignal; private CountDownLatch endSignal; public WorkerI (CountDownLatch begin, CountDownLatch end) {this. beginSignal = begin; this. endSignal = end ;}@ Override public void run () {try {beginSignal. await ();} catch (InterruptedException e) {e. printStackTrace () ;}for (int j = 0; j <CALC_TIME; j ++) {incrAi () ;} endSignal. countDown () ;}} class WorkerVI implements Runnable {private CountDownLatch beginSignal; private CountDownLatch endSignal; public WorkerVI (CountDownLatch begin, CountDownLatch end) {this. beginSignal = begin; this. endSignal = end ;}@ Override public void run () {try {beginSignal. await ();} catch (InterruptedException e) {e. printStackTrace () ;}for (int j = 0; j <CALC_TIME; j ++) {incrVi () ;} endSignal. countDown ();}}}

Program running result:

Calculation Times:1000 ----------------------Total time consumed by atomic increment : 8Total time consumed by synchronized increment : 6Total time consumed by volatile increment : 5Calculation Times:10000 ----------------------Total time consumed by atomic increment : 23Total time consumed by synchronized increment : 24Total time consumed by volatile increment : 15Calculation Times:100000 ----------------------Total time consumed by atomic increment : 354Total time consumed by synchronized increment : 360Total time consumed by volatile increment : 148Calculation Times:1000000 ----------------------Total time consumed by atomic increment : 3579Total time consumed by synchronized increment : 3608Total time consumed by volatile increment : 1519


I suspect that my program has been written incorrectly, but I cannot find the problem for the time being. Please help us with the preparation !)

According to the test results, the efficiency of atomic variables is similar to that of synchronized synchronization, and the efficiency is not obvious. The performance of volatile variables is doubled. Of course, the ++ operation has synchronization problems ), therefore, if the volatile variable can meet the requirements, the volatile variable is preferred, and the atomic variable is second. When will the volatile variable be used? The best practice of expert recommendation is to meet the following three conditions at the same time:

  1. Write operations on variables do not depend on the current value of the variable, or only a single thread can update the value of the variable.

  2. The change quantity does not constitute an immutable condition together with other state variables.

  3. No lock is required when accessing the variable.


Summary of personal practices:

The volatile Boolean variable is used when conditions are met, and the atomic variable is used for other data types.

This article is from "the power comes from the sincere love !" Blog, please be sure to keep this source http://stevex.blog.51cto.com/4300375/1285964

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.