Java并发编程—Atomic原子类
目录
Atomic
1. AtomicInteger
a. 多线程并发访问问题
b. 用 AtomicInteger 类解决
2. AtomicIntegerArray
a. 多线程并发访问问题
b. 用 AtomicIntegerArray 类解决
相关问题
Atomic
在 java.util.concurrent.atomic 包下定义了一些对“变量”操作的“原子类”,它们可以保证对“变量”操作的:原子性、有序性、可见性:
- java.util.concurrent.atomic.AtomicInteger:对 int 变量操作的“原子类”;
- java.util.concurrent.atomic.AtomicLong:对 long 变量操作的“原子类”;
- java.util.concurrent.atomic.AtomicBoolean:对 boolean 变量操作的“原子类”;
1. AtomicInteger
a. 多线程并发访问问题
class MyThread extends Thread {public static volatile int a = 0;@Overridepublic void run() {for (int i = 0; i < 10000; i++) {//线程1:取出a的值a=0(被暂停)a++;//写回}System.out.println("修改完毕!");}
}public class Test {public static void main(String[] args) throws InterruptedException {//1.启动两个线程MyThread t1 = new MyThread();MyThread t2 = new MyThread();t1.start();t2.start();Thread.sleep(1000);System.out.println("获取a最终值:" + MyThread.a);//最终结果仍然不正确。}
}
/*
输出
修改完毕!
修改完毕!
获取a最终值:14791*/
b. 用 AtomicInteger 类解决
import java.util.concurrent.atomic.AtomicInteger;class MyThread extends Thread {//public static volatile int a = 0;//不直接使用基本类型变量//改用"原子类"public static AtomicInteger a = new AtomicInteger(0);@Overridepublic void run() {for (int i = 0; i < 10000; i++) {// a++;a.getAndIncrement();//先获取,再自增1:a++}System.out.println("修改完毕!");}
}public class Test {public static void main(String[] args) throws InterruptedException {//1.启动两个线程MyThread t1 = new MyThread();MyThread t2 = new MyThread();t1.start();t2.start();Thread.sleep(1000);System.out.println("获取a最终值:" + MyThread.a.get());}
}
/*
输出
修改完毕!
修改完毕!
获取a最终值:20000*/
在 Unsafe 类中,调用了一个:compareAndSwapInt() 方法,此方法的几个参数:
- var1:传入的 AtomicInteger 对象
- var2:AtommicInteger 内部变量的偏移地址
- var5:之前取出的 AtomicInteger 中的值
- var5 + var4:预期结果
- 初始 AtomicInteger 的值为0
- 线程A执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:0
- 线程A被暂停
- 线程B执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:0
- 线程B执行:this.compareAndSwapInt(var1,var2,var5,var5 + var4)
- 线程B成功将 AtomicInteger 中的值改为1
- 线程A恢复运行,执行:this.compareAndSwapInt(var1,var2,var5,var5 + var4)
- 此时线程A使用 var1 和 var2 从 AtomicInteger 中获取的值为:1,而传入的 var5 为0,比较失败,返回 false,继续循环
- 线程A执行:var5 = this.getIntVolatile(var1,var2);获取的结果为:1
- 线程A执行:this.compareAndSwapInt(var1,var2,var5,var5 + var4)
- 此时线程A使用 var1 和 var2 从 AtomicInteger 中获取的值为:1,而传入的var5为1,比较成功,将其修改为 var5 + var4,也就是2,将 AtomicInteger 中的值改为2,结束;
CAS 机制也被称为乐观锁机制、自旋锁机制,因为大部分比较的结果为 true,就直接修改了。只有少部分多线程并发的情况会导致 CAS 失败,而再次循环;
2. AtomicIntegerArray
常用的数组操作的原子类,它们可以解决数组的多线程并发访问的安全性问题:
- java.util.concurrent.atomic.AtomicIntegetArray:对 int 数组操作的原子类;
- java.util.concurrent.atomic.AtomicLongArray:对 long 数组操作的原子类;
- java.utio.concurrent.atomic.AtomicReferenceArray:对引用类型数组操作的原子类;
a. 多线程并发访问问题
class MyThread extends Thread {private static int[] intArray = new int[1000];//不直接使用数组@Overridepublic void run() {for (int i = 0; i < getIntArrayLength(); i++) {intArray[i]++;}}public static int getIntArray(int i) {return intArray[i];}public static int getIntArrayLength() {return intArray.length;}
}public class Test {public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 1000; i++) {new MyThread().start();//创建1000个线程,每个线程为数组的每个元素+1}Thread.sleep(1000 * 5);//让所有线程执行完毕System.out.println("主线程休息5秒醒来");for (int i = 0; i < MyThread.getIntArrayLength(); i++) {System.out.println(MyThread.getIntArray(i));}}
}
/*
部分输出
...
999
999
1000
1000
...*/
b. 用 AtomicIntegerArray 类解决
import java.util.concurrent.atomic.AtomicIntegerArray;class MyThread extends Thread {private static int[] intArray = new int[1000];//定义一个数组//改用原子类,使用数组构造public static AtomicIntegerArray arr = new AtomicIntegerArray(intArray);@Overridepublic void run() {for (int i = 0; i < arr.length(); i++) {arr.addAndGet(i, 1);//将i位置上的元素+1}}
}public class Test {public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 1000; i++) {new MyThread().start();}Thread.sleep(1000 * 5);//让所有线程执行完毕System.out.println("主线程休息5秒醒来");for (int i = 0; i < MyThread.arr.length(); i++) {System.out.println(MyThread.arr.get(i));}}
}
/*
输出
1000
1000
1000
1000
...*/
相关问题
Java并发编程—Atomic原子类相关推荐
- Java并发编程实战~原子类
对于简单的原子性问题,还有一种无锁方案,先看看如何利用原子类解决累加器问题. public class Test {AtomicLong count = new AtomicLong(0);publi ...
- Java高并发编程:原子类
1. 并发编程概念 原子性 一个操作不能被再拆分了:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行.一个很经典的例子就是银行账户转账问题. 增量操作符++,不是原 ...
- 「死磕Java并发编程」说说Java Atomic 原子类的实现原理
<死磕 Java 并发编程>系列连载中,大家可以关注一波. 「死磕 Java 并发编程」阿里二面,面试官:说说 Java CAS 原理? 「死磕 Java 并发编程」面试官:说说什么是 J ...
- atomic原子类实现机制_并发编程:并发操作原子类Atomic以及CAS的ABA问题
本文基于JDK1.8 Atomic原子类 原子类是具有原子操作特征的类. 原子类存在于java.util.concurrent.atmic包下. 根据操作的数据类型,原子类可以分为以下几类. 基本类型 ...
- Java并发编程,无锁CAS与Unsafe类及其并发包Atomic
为什么80%的码农都做不了架构师?>>> 我们曾经详谈过有锁并发的典型代表synchronized关键字,通过该关键字可以控制并发执行过程中有且只有一个线程可以访问共享资源,其 ...
- Java并发编程-无锁CAS与Unsafe类及其并发包Atomic
[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/72772470 出自[zejian ...
- Java并发编程包中atomic的实现原理
转载自 Java并发编程包中atomic的实现原理 这是一篇来自粉丝的投稿,作者[林湾村龙猫]最近在阅读Java源码,这一篇是他关于并发包中atomic类的源码阅读的总结.Hollis做了一点点修 ...
- Java多线程进阶面试-Atomic 原子类
1.介绍一下 Atomic 原子类 Atomic 翻译成中文是原子的意思.在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的.在我们这里 Atomic 是指一个操作是不可中断的. ...
- atomic原子类实现机制_深入了解Java atomic原子类的使用方法和原理
在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...
最新文章
- nvidia旧版驱动_N卡用户注意:老版驱动存在5个高危漏洞,赶紧更新
- QUARK的增强版C-QUARK问世,有效提升蛋白质结构从头预测精度
- 【收藏】IDEA中MAVEN项目自动导入依赖的启动与取消
- Android 创建,删除,检测桌面快捷方式
- 数据结构--栈--顺序栈/链式栈(附: 字符括号合法配对检测)
- python实用黑客脚本_Python黑客攻防(十六)编写Dos脚本,进行容易攻击演示
- 基于VUE2.0的分页插件
- 世界上最简单的会计书-笔记
- flutter flutter_screenutil Looking up a deactivated widget‘s ancestor is unsafe.
- GTK:Gdk-CRITICAL **: IA__gdk_draw_pixbuf: assertion ‘GDK_IS_DRAWABLE (drawable)‘ failed
- STM32——TIM1的TIM1_CH1N通道PWM初始化
- Tesseract-OCR对图像和PDF进行光学文字识别
- 我女儿说要看雪,于是我默默的拿起了键盘,下雪咯,程序员就是可以为所欲为!
- VSCode 出现 正在保存“xxxx.vue”: 从 “‘Vetur‘, ‘ESLint‘“(configure)中获取代码操作。
- 走近Ts,用了爽,用后一直爽(一)
- 一张通往计算机世界的地图
- 使用Tushare进行金融时间序列分析研究
- 内存条玄学之四槽插满就这么难么?
- formatDate方法
- 商业地图 | 从肯德基地理分布浅析商业选址