博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
原子操作类介绍
阅读量:3779 次
发布时间:2019-05-22

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

原子操作类介绍

因为java的多线程的缘故,当多个线程同时修改同一个变量,导致最后变量得不到预期的结果。原因是多线程操作,导致变量操作缺少原子性,所以导致变量在多线程的操作下达不到预期效果。

如下面案例所示:

public class Test {    private static int count = 10;    private static AtomicInteger atomicCount = new AtomicInteger(10);    private static final ExecutorService executorService = Executors.newFixedThreadPool(4);    public static void main(String[] args) {        for (int i = 0; i < 10; i++) {            executorService.execute(new Runnable() {                @Override                public void run() {                    atomicExecute();//                    unAtomicExecute();                }            });        }    }    private static void unAtomicExecute() {        try {            Thread.sleep(50);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.print(--count+" ");    }    private static void atomicExecute() {        try {            Thread.sleep(50);//使得效果更明显        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.print( atomicCount.decrementAndGet()+" ");    }}unAtomicExecute()方法执行的结果为:9 9 8 9 7 5 4 6 3 2 atomicExecute()方法执行的结果为:9 6 8 7 5 2 4 3 1 0 从打印的结果看出,unAtomicExecute()出现重复的数字,证明其对数字的操作是不具有原子性的。atomicExecute()使用的是AtomicInteger是具有原子性的。

JavaJDK1.5提供了java.util.concurrent.atomic包(简称Atomic包),这个包中的原子操作类提供了一种用法简单、性能高效、线程安全地更新一个变量的方式。

Atomic包提供4种类型的原子类。

  • 原子更新基本类型

    AtomicBoolean:原子更新布尔类型AtomicInteger:原子更新整型AtomicLong:原子更新长整型

    AtomicBooleanAtomicIntegerAtomicLong的实现相差无几,这里通过AtomicInteger常用API来介绍。

    • AtomicInteger的构造

      public AtomicInteger(int var1) {
      //传入 初始值 this.value = var1;}public AtomicInteger() {
      //默认初始值}
    • 常用方法

      public final int get() {
      //获取当前值 return this.value;}public final void set(int var1) {
      //设置值 this.value = var1;}public final int getAndIncrement() {
      //先获取当前值后在自增1 return unsafe.getAndAddInt(this, valueOffset, 1);}public final int getAndDecrement() {
      ////先获取当前值后在加自减1 return unsafe.getAndAddInt(this, valueOffset, -1);}public final int getAndAdd(int var1) {
      //先获取当前值后再加上传入参数的值 return unsafe.getAndAddInt(this, valueOffset, var1);}public final int incrementAndGet() {
      //先自增1,再获取当前值 return unsafe.getAndAddInt(this, valueOffset, 1) + 1;}public final int decrementAndGet() {
      //先自减1,再获取当前值 return unsafe.getAndAddInt(this, valueOffset, -1) - 1;}public final int addAndGet(int var1) {
      //先加上传入参数的值,再获取当前值 return unsafe.getAndAddInt(this, valueOffset, var1) + var1;}
  • 原子更新数组

    AtomicIntegerArray:原子更新整型数组里的元素AtomicLongArray:原子更新长整型数组里的元素。AtomicReferenceArray:原子更新引用类型数组里的元素

    在java中,提供了许多好用的防并发的容器,所以上面提到的一般都不常用。

  • 原子更新引用

    AtomicReference:原子更新引用类型AtomicReferenceFieldUpdater:原子更新引用类型里的字段AtomicMarkableReference:原子更新带有标记位的引用类型

    这3个类的实现方法基本一样,这里就以AtomicReference写一个示例。

    public class AtomicReferenceTest {           public static AtomicReference
    atomicUserRef = new AtomicReference
    (); public static void main(String[] args) { User user = new User("lisi", 16); atomicUserRef.set(user); System.out.println(atomicUserRef.get().getName() + " " + atomicUserRef.get().getOld()); System.out.println("-------------------------"); User updateUser = new User("zhangsan", 18); atomicUserRef.compareAndSet(user, updateUser); System.out.println(atomicUserRef.get().getName() + " " + atomicUserRef.get().getOld()); } static class User { private String name; private int old; public User(String name, int old) { this.name = name; this.old = old; } public String getName() { return name; } public int getOld() { return old; } } }打印结果:lisi 16-------------------------zhangsan 18
  • 原子更新属性

    AtomicIntegerFieldUpdater:原子更新整型的字段的更新器AtomicLongFieldUpdater:原子更新长整型字段的更新器AtomicStampedReference:原子更新带有版本号的引用类型

    这几个类用的用的比较少,使用方法和上面的类似,类也不复杂,有兴趣可以了解下源码,这里就不写例子了。

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

你可能感兴趣的文章
机器学习之sklearn.preprocessing.LabelBinarizer()的用法
查看>>
决策树剪枝的思想
查看>>
创建二叉树和遍历二叉树
查看>>
算法训练 区间k大数查询
查看>>
算法训练 K好数
查看>>
2021北京交通大学计算机专硕初试经验分享
查看>>
2021北京交通大学计算机专硕复试经验分享
查看>>
简单实现一个数组、链表
查看>>
关于从其他程序切回word文档时卡顿问题的解决办法
查看>>
Linux安装Java环境
查看>>
Java集合 ArrayList原理
查看>>
Git的基本操作
查看>>
简述128陷阱
查看>>
在spring boot项目中修改包名要注意的一些问题
查看>>
编写类实现从后台向前台返回所要求的数据
查看>>
spring boot的学习(1.创建一个初始的spring boot项目)
查看>>
Python的入门学习
查看>>
⑤mpvue 小程序框架 :初始化项目 分析项目结构
查看>>
⑦mpvue Flyio实现前后台交互
查看>>
操作系统:Java模拟CPU调度算法(非抢占短进程优先、可抢占优先权调度、多级反馈队列调度)
查看>>