博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java原子操作类型AtomicInteger安全性的验证和使用
阅读量:2058 次
发布时间:2019-04-29

本文共 2267 字,大约阅读时间需要 7 分钟。

什么是原子操作类?

  • 原子操作类是Java在java.util.concurrent包中提供的线程安全的数据类型,本文主要分析AtomicInteger的线程安全性和使用。

为什么我们需要使用原子操作类来进行数据操作?

  • 因为在多线程环境中,同一个变量可能会被多个线程同时修改,这样就无法保证最终的结果是我们所想要得到的结果,而原子操作类可以在不用手动加锁的情况下保证数据的线程安全。

下面用简单的代码来验证原子操作类的线程安全性:

  • 全局上下文,在这里定义我们要操作的数据实例
public class Context {    public static int addNumTest;//普通的int类型数据    public static AtomicInteger addNum = new AtomicInteger();//原子integer类型}
  • 使用int将数据多线程自加3000000次
private static void testAddNumTest(){    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("1: " + ++Context.addNumTest);            }        }    }).start();    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("2: " + ++Context.addNumTest);            }        }    }).start();    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("3: " + ++Context.addNumTest);            }        }    }).start();}
  • 使用原子操作类将数据多线程自加3000000次
private static void testAddNum(){    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("1: " + Context.addNum.addAndGet(1));            }        }    }).start();    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("2: " + Context.addNum.addAndGet(1));            }        }    }).start();    new Thread(new Runnable() {        @Override        public void run() {            for (int i=0;i<1000000;i++){                System.out.println("3: " + Context.addNum.addAndGet(1));            }        }    }).start();}
  • 这里我们分别创建三个线程同时对数据进行自加操作,每个线程中循环1000000次,我们期望得到的结果是3000000,然而我们实际运行会发现,使用int类型的结果每次都会少于3000000,这是因为其中有多个线程同时操作addNumTest的情况,例如A线程读取到的addNumTest为10,与此同时B线程也读取到addNumTest为10,那么它们都会将计算结果11赋值给addNumTest,然而实际上我们希望的是A线程在计算时,B线程应该等到A线程将计算结果赋值给addNumTest后再进行计算,显然使用AtomicInteger的程序则保证了这一点

  • 这里我将循环次数设置得很大,因为发现循环次数少的话很难出现计算结果偏少的情况,个人猜想,这是因为多线程实际是利用获取CPU时间片来实现多个任务处理的,也就是说,对于一个CPU核心而言,只会有一个活动的线程,并不存在真正的线程并发,循环次数很少时,很短的时间即可处理完成,很难用到CPU的多个核心,所以就很少出现计算结果偏少的情况

转载地址:http://hvtlf.baihongyu.com/

你可能感兴趣的文章
【雅思】【大作文】【审题作业】关于同不同意的审题作业(重点)
查看>>
【Loadrunner】通过loadrunner录制时候有事件但是白页无法出来登录页怎么办?
查看>>
【English】【托业】【四六级】写译高频词汇
查看>>
【托业】【新东方全真模拟】01~02-----P5~6
查看>>
【托业】【新东方全真模拟】03~04-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST05~06-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST09~10-----P5~6
查看>>
【托业】【新东方托业全真模拟】TEST07~08-----P5~6
查看>>
solver及其配置
查看>>
JAVA多线程之volatile 与 synchronized 的比较
查看>>
Java集合框架知识梳理
查看>>
笔试题(一)—— java基础
查看>>
Redis学习笔记(二)— 在linux下搭建redis服务器
查看>>
Redis学习笔记(三)—— 使用redis客户端连接windows和linux下的redis并解决无法连接redis的问题
查看>>
Intellij IDEA使用(一)—— 安装Intellij IDEA(ideaIU-2017.2.3)并完成Intellij IDEA的简单配置
查看>>
Intellij IDEA使用(二)—— 在Intellij IDEA中配置JDK(SDK)
查看>>
Intellij IDEA使用(三)——在Intellij IDEA中配置Tomcat服务器
查看>>
Intellij IDEA使用(四)—— 使用Intellij IDEA创建静态的web(HTML)项目
查看>>
Intellij IDEA使用(五)—— Intellij IDEA在使用中的一些其他常用功能或常用配置收集
查看>>
Intellij IDEA使用(六)—— 使用Intellij IDEA创建Java项目并配置jar包
查看>>