JAVA 原子操作类
上文中,guava代码中就用到了,在这里再专门捋一下
部分内容源自:
https://www.jianshu.com/p/712681f5aecd
https://www.yiibai.com/java_concurrency/concurrency_atomiclong.html
AtomicReferenceArray<ReferenceEntry<K, V>>
①原子更新基本类型:
AtomicBoolean、AtomicInteger、AtomicLong②原子更新数组:
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray③原子更新引用:
AtomicReference、AtomicReferenceFiledUpdater、AtomicMarkableReference④原子更新字段(属性):
AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference它们都是使用Unsafe实现的包装类。
Executor executor = Executors.newFixedThreadPool(3);
AtomicInteger atomicInteger = new AtomicInteger(0);
for(int i = 0; i < 10; i++){
executor.execute(()->{
System.out.println("atomicInteger的当前值:" + atomicInteger.addAndGet(1));
});
}

原子更新数组,例AtomicReferenceArray,用法抄自上文,实际就是基于cas的操作
public class MainTest {
private static String[] source = new String[10];
private static AtomicReferenceArray<String> atomicReferenceArray = new AtomicReferenceArray<String>(source);
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < atomicReferenceArray.length(); i++) {
atomicReferenceArray.set(i, "item-2");
}
Thread t1 = new Thread(new Increment());
Thread t2 = new Thread(new Compare());
t1.start();
t2.start();
t1.join();
t2.join();
}
static class Increment implements Runnable {
public void run() {
for (int i = 0; i < atomicReferenceArray.length(); i++) {
String add = atomicReferenceArray.getAndSet(i, "item-" + (i + 1));
System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: " + add);
}
}
}
static class Compare implements Runnable {
public void run() {
for (int i = 0; i < atomicReferenceArray.length(); i++) {
System.out.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", value: "
+ atomicReferenceArray.get(i));
boolean swapped = atomicReferenceArray.compareAndSet(i, "item-2", "updated-item-2");
System.out.println("Item swapped: " + swapped);
if (swapped) {
System.out
.println("Thread " + Thread.currentThread().getId() + ", index " + i + ", updated-item-2");
}
}
}
}
}
AtomicReferenceFiledUpdater https://github.com/aCoder2013/blog/issues/10 这个blog写的真不错,在jdk中有很多应用。比如对buf的更新等
一个基于反射的工具类,它能对指定类的指定的volatile引用字段进行原子更新。(注意这个字段不能是private的)
class Node {
private volatile Node left, right;
private static final AtomicReferenceFieldUpdater<Node, Node> leftUpdater =
AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left");
private static AtomicReferenceFieldUpdater<Node, Node> rightUpdater =
AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right");
Node getLeft() { return left; }
boolean compareAndSetLeft(Node expect, Node update) {
return leftUpdater.compareAndSet(this, expect, update);
}
// ... and so on
}}
public
class BufferedInputStream extends FilterInputStream { protected volatile byte buf[]; /*
* 原子的更新内部数组,比如扩容、关闭时,
*/
private static final
AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
AtomicReferenceFieldUpdater.newUpdater
(BufferedInputStream.class, byte[].class, "buf"); public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
//放在一个循环中,如果CAS更新失败,那么就读取最新的buf引用,继续CAS更新
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
}
}
}
AtomicStampedReference 通过包装[E,Integer]的元组来对对象标记版本戳stamp,从而避免ABA问题
JAVA 原子操作类的更多相关文章
- Java 并发系列之九:java 原子操作类Atomic(13个)
1. 原子更新基本类型类 2. 原子更新数组 3. 原子更新引用 4. 原子更新属性 5. txt java 原子操作类Atomic 概述 java.util.concurrent.atomic里的原 ...
- Java原子操作类AtomicInteger应用场景
Java中有那么一些类,是以Atomic开头的.这一系列的类我们称之为原子操作类.以最简单的类AtomicInteger为例.它相当于一个int变量,我们执行Int的 i++ 的时候并不是一个原子操作 ...
- Java原子操作类汇总
当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...
- Java原子操作类,你知道多少?
原子操作类简介 由于synchronized是采用的是悲观锁策略,并不是特别高效的一种解决方案. 实际上,在J.U.C下的atomic包提供了一系列的操作简单,性能高效,并能保证线程安全的类去 更新基 ...
- Java原子操作类汇总(2)
当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...
- 【Java多线程】Java 原子操作类API(以AtomicInteger为例)
1.java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicLong,AtomicLongArray, AtomicRef ...
- java中的原子操作类AtomicInteger及其实现原理
/** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncremen ...
- java并发编程基础 --- 7章节 java中的13个原子操作类
当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...
- 并发之java.util.concurrent.atomic原子操作类包
15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...
随机推荐
- go语言学习--指针的理解
Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int 及 float 系列,高级类型包含 struct,array/slice,map,chan, fu ...
- DevOps安装、部署持续集成
1.重启docker服务,开启iptables转发功能 # systemctl start docker # vi /etc/sysctl.conf # sysctl -p [root@localho ...
- java打印实心10*10正方形, 空心10*10正方形
public class PrintSquare { public static void main(String[] args) { printSolidSquare(10); System.out ...
- SAS DATA ENCODING 解决odbc乱码问题
首先获取编码格式: %PUT %SYSFUNC(getOption(ENCODING)); libname findoout ODBC datasrc=SurveyReport user=shendu ...
- ORACLE 通过连接查询更新 update select
注意: 关键的地方是where 语句的加入. 在11G中, 如果不加11G , 或造成除匹配的行数更新为相应的值之后, 其余的会变成负数. 所以,执行前需要测试, 普通办法就是: 先查看需要更新的 ...
- 第9课 基于范围的for循环
1. 基于范围的for循环(range-based for) (1)语法:for(decl : coll){//statement} ①decl用于声明元素及类型,如int elem或auto ele ...
- Html5——视频标签使用
video标签: 上面的例子使用一个 Ogg 文件,适用于Firefox.Opera 以及 Chrome 浏览器.要确保适用于 Safari 浏览器,视频文件必须是 MPEG4 类型.video 元素 ...
- MVP与MVC的区别
MVP的主要思想就是解耦View和Model 先大致从图上看一下MVP和MVC又什么不同: MVC: M : Model 数据模型,就是对数据的封装和保存: V : View 视图界面,相当于布局文件 ...
- shell脚本遍历子目录
#!/bin/bashsource /etc/profile tool_path=/data/rsync_clientroot_path=/data/log ####yyyy-mm-dd¸ñʽdat ...
- webstorm命令行无法使用node-gyp进行编译
换成cmd命令即可: