上文中,guava代码中就用到了,在这里再专门捋一下

部分内容源自:

https://www.jianshu.com/p/712681f5aecd

https://www.yiibai.com/java_concurrency/concurrency_atomiclong.html

AtomicReferenceArray<ReferenceEntry<K, V>>
根据变量类型的不同,Atomic包中的这12个原子操作类可以分为4种类型:
①原子更新基本类型AtomicBoolean、AtomicInteger、AtomicLong
②原子更新数组AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
③原子更新引用AtomicReference、AtomicReferenceFiledUpdater、AtomicMarkableReference
④原子更新字段(属性)AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicStampedReference
它们都是使用Unsafe实现的包装类。
 
对于原子更新类基本操作,可以看到AtomicInteger中基本有以下一些方法,其他也都差不多,用法简单
        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 原子操作类的更多相关文章

  1. Java 并发系列之九:java 原子操作类Atomic(13个)

    1. 原子更新基本类型类 2. 原子更新数组 3. 原子更新引用 4. 原子更新属性 5. txt java 原子操作类Atomic 概述 java.util.concurrent.atomic里的原 ...

  2. Java原子操作类AtomicInteger应用场景

    Java中有那么一些类,是以Atomic开头的.这一系列的类我们称之为原子操作类.以最简单的类AtomicInteger为例.它相当于一个int变量,我们执行Int的 i++ 的时候并不是一个原子操作 ...

  3. Java原子操作类汇总

    当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...

  4. Java原子操作类,你知道多少?

    原子操作类简介 由于synchronized是采用的是悲观锁策略,并不是特别高效的一种解决方案. 实际上,在J.U.C下的atomic包提供了一系列的操作简单,性能高效,并能保证线程安全的类去 更新基 ...

  5. Java原子操作类汇总(2)

    当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...

  6. 【Java多线程】Java 原子操作类API(以AtomicInteger为例)

    1.java.util.concurrent.atomic 的包里有AtomicBoolean, AtomicInteger,AtomicLong,AtomicLongArray, AtomicRef ...

  7. java中的原子操作类AtomicInteger及其实现原理

    /** * 一,AtomicInteger 是如何实现原子操作的呢? * * 我们先来看一下getAndIncrement的源代码: * public final int getAndIncremen ...

  8. java并发编程基础 --- 7章节 java中的13个原子操作类

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量 i=1,A线程更新 i+1,B线程也更新 I+1,经过两个线程的操作之后可能 I不等于3,而是等于2.因为A和B线程更 ...

  9. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

随机推荐

  1. CDN上的缓存刷新、缓存预热是怎样的使用场景?

    缓存刷新 源站内容更新后,希望用户可以获取到最新资源,CDN租户可以通过提交刷新请求将CDN节点上指定的缓存内容强制过期.当用户再次访问时,CDN节点将回源获取已更新内容返回给用户并在节点缓存最新资源 ...

  2. 第一天课程:第一个python程序print say hello

    print("Hello World") linux下要加可执行权限 chmod 755 hello.py 权限755,7=4+2+1,4是读,2是写,1是执行,第一个7代表用户, ...

  3. 00001 - Linux 上的 Shebang 符号(#!)

    使用Linux或者unix系统的同学可能都对#!这个符号并不陌生,但是你真的了解它吗? 本文了将给你简单介绍一下Shebang(”#!”)这个符号. 首先,这个符号(#!)的名称,叫做”Shebang ...

  4. mysql数据备份与操作

    物理备份: 直接复制数据库文件,适用于大型数据库环境.但不能恢复到异构系统中如Windows. 逻辑备份: 备份的是建表.建库.插入等操作所执行SQL语句,适用于中小型数据库,效率相对较低. 导出表: ...

  5. JS面试典型常见问题与解答

    Q1:下面代码段的输出是什么? 为什么? (Scope) (function() { var a = b = 5; })(); console.log(b); A1: 输出是5. 在上面的立即调用函数 ...

  6. 百度UEditor粘贴或插入的表格不显示边框的解决办法

    原文链接:http://blog.csdn.net/lovelyelfpop/article/details/51678742 参考:https://www.cnblogs.com/xiangsj/p ...

  7. 小朋友学C语言(4):单精度浮点数与双精度浮点数

    上节课简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的单 ...

  8. shell脚本选择LOG里面特定的行,生成新文件并rsync上传

    rsync.sh #!/bin/bash tool_path=$(cd `dirname $`; pwd) eval `cat ${tool_path}/conf.properties` rsync_ ...

  9. Shell流程控制(if,else,case,while,for,until)

    1.条件选择 1.1.if 语句 语法十分简单 #!/bin/bash MATH_SCORES="$1" NAME="$2" if [ -z "${M ...

  10. Python模块学习 - jinja2

    模板 要了解jinja2,那么需要先理解模板的概念.模板在Python的web开发中广泛使用,它能够有效的将业务逻辑和页面逻辑分开,使代码可读性增强.并且更加容易理解和维护. 模板简单来说就是一个其中 ...