atomic原子类实现机制_JUC学习笔记--Atomic原子类
Atomic 原子操作类包
Atomic包 主要是在多线程环境下,无锁的进行原子操作。核心操作是基于UnSafe类实现的CAS方法
CAS
CAS: compareAndSwap :传入两个值:期望值和新值,判断原有值与期望值相等,则给其赋新值,否则不做任何操作。
CAS硬件支持
现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰。
Atomic源码
以AtomicInteger为例(AtomicBoolean也是把boolen转为int)
public class AtomicInteger extends Number implements java.io.Serializable {
//序列化相关
private static final long serialVersionUID = 6214790243416807050L;
//Unsafe类
private static final Unsafe unsafe = Unsafe.getUnsafe();
//内存地址偏移量
private static final long valueOffset;
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
//value值,因为无锁使用volatile保证线程加载到最新的值
private volatile int value;
//初始化
public AtomicInteger(int initialValue) {
value = initialValue;
}
public AtomicInteger() {
}
//获取当前值
public final int get() {
return value;
}
//赋值
public final void set(int newValue) {
value = newValue;
}
//延迟赋值,不保证新的赋值能立即被其他线程获取到
public final void lazySet(int newValue) {
unsafe.putOrderedInt(this, valueOffset, newValue);
}
//返回旧值并赋新值
public final int getAndSet(int newValue) {
for (;;) {// 等同于while(true)
int current = get();//获取旧值
if (compareAndSet(current, newValue))//以CAS方式赋值,直到成功返回
return current;
}
}
//对比期望值与value,不同返回false。相同将update赋给value 返回true
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
//与compareAndSet实现相同(可能为了以后更改)
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
//自增 i++
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
//自减 i--
public final int getAndDecrement() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
}
//自定义增量数
public final int getAndAdd(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
}
//++i 返回自增后的值
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
//--i 返回减少后的值
public final int decrementAndGet() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
}
//返回加上delta后的值
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
/**
* Returns the String representation of the current value.
* @return the String representation of the current value.
*/
public String toString() {
return Integer.toString(get());
}
public int intValue() {
return get();
}
public long longValue() {
return (long)get();
}
public float floatValue() {
return (float)get();
}
public double doubleValue() {
return (double)get();
}
}
CAS的ABA问题
ABA问题:有两个线程,x线程读取值为A ,y线程读取值为A 并赋值为B,B线程再修改会A,此时x线程以A为旧值并赋新值仍然是成功的,
因为线程x不知道变量值经过A->B->A的修改。
AtomicStampedReference 解决ABA问题
先看看如何使用:
AtomicStampedReference asr= new AtomicStampedReference(1,0);
int stamp= asr.getStamp();
System.out.println(asr.compareAndSet(1,2,stamp,stamp+1));//true
System.out.println(asr.compareAndSet(2,1,stamp,stamp+1));//false
System.out.println(asr.compareAndSet(1,1,stamp+1,stamp+2));//false
System.out.println(asr.getReference());//2
对比AtomicInteger,可见AtomicStampedReference的构造函数多了一个参数、compareAndSet方法多了两个参数,看一下源码:
//对比AtomicInteger构造函数多了stamp参数
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
}
private static class Pair {
final T reference;
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static Pair of(T reference, int stamp) {
return new Pair(reference, stamp);
}
}
//对比AtomicInteger value由int 改为Pair
private volatile Pair pair;
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
Pair current = pair;
return
expectedReference == current.reference && //判断期望值与旧值是否相同
expectedStamp == current.stamp && //判断期望版本戳与旧版本戳是否相同
((newReference == current.reference &&
newStamp == current.stamp) || //如果值和戳没变化不执行下一行cas赋值代码
casPair(current, Pair.of(newReference, newStamp)));//cas赋值代码
}
//还是调用unsafe类
private boolean casPair(Pair cmp, Pair val) {
return UNSAFE.compareAndSwapObject(this, pairOffset, cmp, val);
}
JUC 中的 Atomic 原子类总结
1 Atomic 原子类介绍 Atomic 翻译成中文是原子的意思.在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的.在我们这里 Atomic 是指一个操作是不可中断的.即使是 ...
Juc中Atomic原子类总结
1 Atomic原子类介绍 2 基本类型原子类 3 数组类型原子类 4 引用类型原子类 5 对象的属性修改类型原子类
(转)Java atomic原子类的使用方法和原理(一)
在讲atomic原子类之前先看一个小例子: public class UseAtomic { public static void main(String[] args) { AtomicIntege ...
Atomic原子类
Atomic原子类 Atomic原子类位于并发包java.util.concurrent下的java.util.concurrent.Atomic中. 1. 原子更新基本类型类 使用原子方式更新基本数 ...
多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
[Java多线程]-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
J.U.C 系列之Atomic原子类
一 什么是原子类? 所谓原子类必然是具有原子性的类,原子性操作--原子操作,百度百科中给的定义如下 "原子操作(atomic operation)是不需要synchronized" ...
Spring.NET学习笔记——目录(原)
目录 前言 Spring.NET学习笔记——前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1——控制反转(基础篇) Level 200 Spring.NET学习笔 ...
随机推荐
[汇编与C语言关系]4. 结构体和联合体
用反汇编的方法研究一下C语言的结构体: #include int main(int argc, char ** argv) { struct { char a; sho ...
AndroidStudio学习笔记-第一个安卓程序
要带一个本科生做一部分跟安卓有点关系的项目,于是趁着机会学习一下编写安卓程序. 第一篇材料来自谷歌官方,传送门:https://developer.android.com/training/basic ...
windows 10
http://auPL.v4.b1.download.windowsupdate.com/c/updt/2015/07/10240.16384.150709-1700.th1_clientchina_ ...
Android蓝牙连接以及数据接收发送
1.加入权限
CSS 高级技巧汇总
在我们平时写代码的时候没有没有掌握一些CSS技巧呢? 今天给大家分享一个.大家务必掌握这些小技巧,会让你非常高效率的写出网页的. ◆使用 :not ...
微信小程序简单入门1
参考文档:https://mp.weixin.qq.com/debug/wxadoc/dev/index.html 1 创建项目 开发者工具安装完成后,打开并使用微信扫码登录.选择创建"项 ...
遇到的问题&;思考
MYSQL需要批量修改表前缀: http://jingyan.baidu.com/article/11c17a2c742561f446e39d2f.html Select CONCAT( 'ALTER ...
PhysicalDrive
由于"\"是C/C+中转义符, "\\\\.\\"就相当于\\.\ 在Windows中 \\.\ 前缀用于标识设备,其中的"."表示本地计算 ...
Delphi字符串、PChar与字符数组之间的转换
来自:http://my.oschina.net/kavensu/blog/193719 ------------------------------------------------------- ...
java 中的valueOf方法和强转
case1:Object 对象转String 需要强调的是String.valueOf()方法,当参数为类型是object,且值时null的时候他的处理方式 public static String ...
atomic原子类实现机制_JUC学习笔记--Atomic原子类相关推荐
- Spring.NET学习笔记——目录(原)
目录 前言 Spring.NET学习笔记--前言 第一阶段:控制反转与依赖注入IoC&DI Spring.NET学习笔记1--控制反转(基础篇) Level 200 Spring.NET学习笔 ...
- C# 子类实例化基类 基类使用不了子类的方法_C#学习笔记09--构造方法/析构方法/继承/多态/封装...
一.构造方法 当创建一个类时, 系统会自动创建一个默认的无参构造方法, 这个方法和类同名, 在创建对象的时候自动调用. 默认的构造方法里面什么也没有, 重写之后就可以在创建对象的时候同时搞点事情了. ...
- atomic原子类实现机制_Java并发包-atomic包-让您彻底掌握AtomicInteger源码
从这一篇文章开始,我开始对并发包的atomic包进行源码解析,首先通过下面的图了解以下atomic包中的类都是有哪些? atomic包中的所有类 这一篇文章首先对AtomicInteger进行讲解.在 ...
- TVM中的auto-scheduling机制(Ansor)学习笔记
背景 TVM继承了Halide中算法(Algorithm)与调度(Schedule)分离的思想.用户使用TE(Tensor expression)这种DSL定义计算(算法),然后编译器优化相应的sch ...
- NumPy————NumPy广播机制的学习笔记
1 致谢 感谢网友"FINTHON"的帮助, 原文链接如下: https://finthon.com/numpy-broadcast/ 2 前言 今天在学习K-means算法~ 想 ...
- Java并发23:Atomic系列-普通原子类型AtomicXxxx学习笔记
[超级链接:Java并发学习系列-绪论] [系列概述: Java并发22:Atomic系列-原子类型整体概述与类别划分] 本章主要对普通原子类型进行学习. 1.普通原子类型 在java.util.co ...
- C# 子类实例化基类 基类使用不了子类的方法_C#学习笔记11--接口/泛型
一.接口 1.1简介: 接口是一种特殊的引用类型, 和类很相似. 它定义了属性, 方法, 事件, 这些都作为接口的成员/ 接口中只包含成员的声明, 成员的定义是派生类的责任(谁继承谁实现). 接口在某 ...
- python函数参数传递机制_Python 学习笔记(一) 理解Python的函数传参机制
对于刚接触Python不久的新手,Python的函数传参机制往往会让人迷惑.学过C的同学都知道函数参数可以传值或者传地址.比如下面这段代码 点击(此处)折叠或打开 void func(int inpu ...
- 计算机视觉中的注意力机制的学习笔记
1 介绍 关于注意力机制(Attension)的综述请参考博文<综述|计算机视觉中的注意力机制> 关于Attention机制,我总觉得是一个很有趣的话题,因为根据"万能拟合器&q ...
最新文章
- MySQL 讨厌哪种类型的查询
- php tp5 redis的使用(亲测)
- 接入淘宝API(PHP版本)
- java 运行 .jar 文件乱码
- OpenCV学习笔记(十八):凸包,最小包围区域算子:convexHull(),minAreaRect(),minEnclosingTriangle(),minEnclosingCircle()
- linux下nmap工具的使用
- [转] 面向对象编程 - 类和实例
- node.js 数据库操作工具类封装
- Android图片加载那些事(一)-实现加载手机中的所有图片
- 使用arcgis、matlab与R语言GD包进行地理探测器 批量运行,并导出探测结果
- Vue开发环境搭建详解
- 【DC-DC开关电源芯片的使用(LM2596)】
- 无监督学习——非负矩阵分解(NMF)
- 铜陵学院计算机程序设计大赛,ACM程序设计大赛
- android 多语言国家化对照表(超详细)
- 10个每个人都用得到的视频下载网站
- 国内工业机器人发展水平综述
- css —— 文字添加白色描边
- MFC修改界面图标时,已导入.ico文件,但是程序运行后,界面不显示更新后的新图标
- 一入IT深似海 从此妹子为路人