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原子操作类包 ...
随机推荐
- 廖雪峰Java4反射与泛型-3泛型-7泛型和反射
1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...
- postgresql小纪
本来是想在PaaS环境中定位PG数据库的问题,却发现给每个PG实例,就是每个库,分配的密码是加密的,还不能直接查看密码. 登录PG数据库对应的容器,发现使用默认的用户postgres没有密码也可以正常 ...
- mysql 删除表 外键出错
MySQL库中有俩表,table1和table2,相互关联,在删除表的时候出错: Cannot delete or update a parent row: a foreign key constra ...
- CGo中传递多维数组给C函数
转自:http://www.cnblogs.com/cobbliu/p/5035358.html package main /* #include <stdio.h> #include & ...
- Jensen不等式
- win10使用4G 模块RNDIS模式上网
Windons使用RNDIS模式上网步骤 Chapter 1 模块端配置 1模块设置为RNDIS模式 1. 以EC20CEFAG模块为例 2. 命令如下: 1) ...
- 几个常用的SQL 时间函数
--当月第一天declare @startFirstDate datetimeset @startFirstDate=dateadd(dd,datediff(dd,0,getdate()),-day( ...
- 10 Skills Every SharePoint Developer Needs
10 Skills Every SharePoint Developer Needs(原文) This blog post guides you through the essential skill ...
- U3D学习09-物体简单控制及视角观察
一.Character Control非刚体 1.场景初始化,注意调整CC的轴心,不需要碰撞,且删除CC子物体的碰撞.2.移动: 获取X,Z轴变化,定义变量h,v: 定义移动 ...
- html跳页面传值
从a.html跳转到b.html并且把a.html的值name传入b.html 在a.html页面,url路径后面带参数,参数与url之间用?隔开 window.location.href = &q ...