AtomicInteger的使用

Posted 专注着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtomicInteger的使用相关的知识,希望对你有一定的参考价值。

    最近在看关于分布式应用开发相关的书籍,发现在书中提到了关于线程安全的一些不常见的类的用法,所以下来就自己花了一点时间看了一点API文档。下面是我的一点总结。

一、API文档说明

Package java.util.concurrent.atomic Description

     A small toolkit of classes that support lock-free thread-safeprogramming on single variables. In essence, the classes in thispackage extend the notion of volatile values, fields, andarray elements to those that also provide an atomic conditional updateoperation of the form


     这是关于java.util.concurrent.atomic的包中说明,该包下面提供了一下线程安全的操作类,以保证数据的原子性。(相当于保证线程间获取的到数据是最新的)。这些类的实现,主要通过使用volatile来修饰属性,具体可以查询用法。


二、示例

     下面通过一个示例来说明他的用法:

        该例子主要实现 0 ~ 100的和,只不过我们不采用单线程的方式,而是采用多线程实现

       (1)如果采用多线程,一般采用的方法是,定义一个count的变量,然后通过为count加上数据。在多线程中,为了保证数据的原子性,可能会采用synchronized 关键字,来保证并发下count的值始终为修改后的值。(这里就不给出实例,可以自己尝试一下,应该还是比较简单)

        (2)采用AtomicInteger

                先给出代码:

               

package org.java.se.util.concurrent;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * AtomicInteger 能够保证数据的原始性,是一个线程安全的类
 * @author xianglj
 * @date 2016/7/12
 * @time 9:59
 */
public class AutomicIntegerTest 
    private static AtomicInteger atomic = new AtomicInteger(0);
    //初始化数据,等到所有线程都执行完操作之后,在进行下一步
    private static CountDownLatch latch = new CountDownLatch(101);

    /**
     * 固定三个线程来计算值
     */
    private static ExecutorService service = Executors.newFixedThreadPool(3);

    /**
     * 采用多线程的方式来计算0-100的和
     * @param args
     */
    public static void main(String[] args) 
        //通过多线程的方式来对数据进行操作
        for(int i = 0, len = 100; i <= len; i++) 
            final int scale = i;
            Runnable r = new Runnable() 
                @Override
                public void run() 
                    atomic.addAndGet(scale);
                    latch.countDown();
                
            ;
            service.submit(r);
        

        try 
            //等到所有的线程都执行了countDown一次之后,在继续向下执行
            latch.await();
         catch (InterruptedException e) 
            e.printStackTrace();
        

        //输出最终的值
        System.out.println("0~100的和为:" + (atomic.get()));
    


在代码中,我们先为AtomicInteger初始化一个值,然后我们采用addAndGet(int val); 方法加上指定值,然后采用线程池来执行程序。因为这是多线程,当我们把循环执行完成之后,输出atomicInteger中最终的值,会发现可能是0,这是因为循环完成,可能线程还没有执行完成,所以我们获取到的数据可能不是最新的数据,因此,我们使用了CountDownLatch类,该类采用计数的方式,await()方式,能够使线程阻塞,并等到其他线程执行完countDown()方法后,会继续执行。这样当我们再次执行到输出行时,就能够保证所有的线程都已经执行完成,获得最终的结果。


输出结果:

0~100的和为:5050



以上是关于AtomicInteger的使用的主要内容,如果未能解决你的问题,请参考以下文章

AtomicInteger简介

AtomicInteger简介

JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用

java中关于AtomicInteger的使用

AtomicInteger在实际项目中的应用

AtomicInteger 源码分析阅读