并发编程的艺术第七章-13个原子类介绍

java中的13个原子类操作

13个原子类操作主要分为四大类:原子更新基本类型,原子更新数组,原子更新引用,原子更新属性(字段)

atomic 的类基本都是unsafe类的包装类

原子更新基本类型包括:

atomicBoolean

atomicIneger

atomicLong

这里注意lazyset方法,Doug Lea大神已经在oracle官网解释了,原文如下

"As probably the last little JSR166 follow-up for Mustang,
we added a "lazySet" method to the Atomic classes
(AtomicInteger, AtomicReference, etc). This is a niche
method that is sometimes useful when fine-tuning code using
non-blocking data structures. The semantics are
that the write is guaranteed not to be re-ordered with any
previous write, but may be reordered with subsequent operations
(or equivalently, might not be visible to other threads) until
some other volatile write or synchronizing action occurs).

The main use case is for nulling out fields of nodes in
non-blocking data structures solely for the sake of avoiding
long-term garbage retention; it applies when it is harmless
if other threads see non-null values for a while, but you‘d
like to ensure that structures are eventually GCable. In such
cases, you can get better performance by avoiding
the costs of the null volatile-write. There are a few
other use cases along these lines for non-reference-based
atomics as well, so the method is supported across all of the
AtomicX classes.

For people who like to think of these operations in terms of
machine-level barriers on common multiprocessors, lazySet
provides a preceeding store-store barrier (which is either
a no-op or very cheap on current platforms), but no
store-load barrier (which is usually the expensive part
of a volatile-write)."
###@###.### 2005-05-24 17:04:

外链地址如下

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6275329

大概意思就是使用该方法取掉了 storeload屏障,只保留storestore屏障,

在屏障中storeload屏障是最耗资源的,因此使用该方法对提高效率有一定好处,虽然不能保证写完之后立即被其他线程可见,但是能保证写的顺序,同时该方法职能处理有volatile的对象,使用该方法要注意一定的使用场景。

典型的atomicInteger的getAndIncrement方法如下:

public final int getAndIncrement(){

int current=get();

while(true){

if(compareandset(current,current+1)){

return current;

}

}

//compareandset 使用unsafe类实现

public final boolean compareandset(int expect ,int update){

unsafe.compareandswapint(this,expect,valueoffset,update);

}

}

根据unsafe类提供的swap方法,在使用时需要将包装类转换成基本类型再使用unsafe类中的compareandswap方法

在atomic包中,并没有提供 char float double 类型的swap方法,可以采用转换成object包装类,或者转换成long类型进行处理

更新原子数组类

AtomicIntegerArray

AtomicLongArray

AtomicReferenceArray

//使用代码实例

public class AtomicIntegerArrayTest{

static int[] value=new int[2]{1,2};

static AtomicIntegerArray ai = new AtomicInteger(value);

public static void main(String[] args){

ai.getandset(0,3);//设置第一位为3

System.out.println(ai.get(0));// 结果3

System.out.println(value[0]);//结果1

}

}

根据伪代码结果发现结果不一致,主要原因:ai通过构造方法复制了一份value所以对ai修改时,不会影响value的值

原子更新引用类型

原子更新基本类型的AtomicInteger,只能更新一个变量,如果更新多个变量就需要使用原子更新引用类

AtomicReference 原子更新引用类型

AtomicReferenceFieldUpdater 原子更新引用对象里的字段

AtomicMarkableReference 原子更新带有标记位的引用类型

原子更新引用类型的字段

如果需要原子更新引用对象的字段时,就需要使用原子更新字段类,atomic包包含了以下工具类

AtomicIntegerFieldUpdater

AtomicLongFieldUpdate

AtomicStampedReference:原子更新带有版本号的引用类型,可用于原子更新的版本号和引用数据,可以有效解决原子更新的aba问题。原子更新主要分为两步:因为原始更新字段类都是抽象类,必须使用静态方法 newUpdater()创建一个更新器,并且需要设置更新器的类型和属性,第二步,更新类的字段必须使用 public volatitle字段进行修饰

调用伪代码如下:

public class FieldUpdater{

AtomicIntegerFieldUpdater a = AtomicIntegerFieldUpdater.newUpdater(User.class,age);

static class User{

private String name;

private volatitle int age;

}

public static void main(String[] args){

User coman = new User("coman",10);

System.out.println(a.getAndIncrement(coman));

System.out.println(a.get(coman));

}

}

时间: 2024-10-13 09:26:40

并发编程的艺术第七章-13个原子类介绍的相关文章

java并发编程实战:第七章----取消与关闭

Java没有提供任何机制来安全地终止线程(虽然Thread.stop和suspend方法提供了这样的机制,但由于存在缺陷,因此应该避免使用 中断:一种协作机制,能够使一个线程终止另一个线程的当前工作 立即停止会使共享的数据结构处于不一致的状态,需要停止时,发出中断请求,被要求中断的线程处理完他当前的任务后会自己判断是否停下来 一.任务取消 若外部代码能在某个操作正常完成之前将其置入"完成"状态,则还操作是可取消的.(用户请求取消.有时间限制的操作<并发查找结果,一个线程找到后可取

《Java并发编程实战》第七章 取消与关闭 读书笔记

Java没有提供不论什么机制来安全地(抢占式方法)终止线程,尽管Thread.stop和suspend等方法提供了这种机制,可是因为存在着一些严重的缺陷,因此应该避免使用. 但它提供了中断Interruption机制,这是一种协作机制,可以使一个线程终止还有一个线程的当前工作. 一.任务取消 取消操作的原因: . 用户请求取消 . 有时间限制的操作 . 应用程序事件 . 错误 . 关闭 结束任务的四种方式: 1. run方法运行结束 2. 使用请求关闭标记(比如boolean开关) 3. 使用中

java并发编程的艺术——第五章总结(Lock锁与队列同步器)

Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchronized关键字实现锁的功能,但是在javaSE5之后,并发包中提供了Lock接口(以及其实现类)用来实现锁的功能. Lock提供了与synchronized相似的功能,但必须显示的获取锁与释放锁,虽然不及隐式操作方便,但是拥有了锁获取与释放的可操作性.可中断的锁获取与超时获取锁等多重功能. 提供

《java并发编程的艺术》读书笔记-第三章Java内存模型(二)

一概述 本文属于<java并发编程的艺术>读书笔记系列,第三章java内存模型第二部分. 二final的内存语义 final在Java中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.可以参照之前整理的关键字final.这里作者主要介绍final域的内存语义. 对于final域,编译器和处理器要遵守两个重排序规则: 在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序. 初次读一个包含final域的对象的引用,与随后初次读这

&lt;java并发编程的艺术&gt;读书笔记-第三章java内存模型(一)

一概述 本文属于<java并发编程的艺术>读书笔记系列,继续第三章java内存模型. 二重排序 2.1数据依赖性 如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性.数据依赖分下列三种类型: 名称 代码示例 说明 写后读 a = 1;b = a; 写一个变量之后,再读这个位置. 写后写 a = 1;a = 2; 写一个变量之后,再写这个变量. 读后写 a = b;b = 1; 读一个变量之后,再写这个变量. 上面三种情况,只要重排序两个操作的执行顺序,

Java并发编程的艺术下载 &#155949;

下载地址: http://www.gqylpy.com/di/11 <Java并发编程的艺术>PDF高清完整版-下载 内容简介 并发编程领域的扛鼎之作,作者是阿里和1号店的资深Java技术专家,对并发编程有非常深入的研究,<Java并发编程的艺术>是他们多年一线开发经验的结晶.本书的部分内容在出版早期发表在Java并发编程网和InfoQ等技术社区,得到了非常高的评价.它选取了Java并发编程中核心的技术进行讲解,从JDK源码.JVM.CPU等多角度全面剖析和讲解了Java并发编程的

读《Java并发编程的艺术》(一)

离开博客园很久了,自从找到工作,到现在基本没有再写过博客了.在大学培养起来的写博客的习惯在慢慢的消失殆尽,感觉汗颜.所以现在要开始重新培养起这个习惯,定期写博客不仅是对自己学习知识的一种沉淀,更是在督促自己要不断的学习,不断的进步. 最近在进一步学习Java并发编程,不言而喻,这部分内容是很重要的.现在就以<并发编程的艺术>一书为主导线,开始新一轮的学习. 进程和线程 进程是一个应用程序在处理机上的一次执行过程,线程是进程的最小基本单位(个人理解).一个进程可以包含多个线程. 上下文切换 我们

《C++ 并发编程》- 第1章 你好,C++的并发世界

<C++ 并发编程>- 第1章 你好,C++的并发世界 转载自并发编程网 – ifeve.com 本文是<C++ 并发编程>的第一章,感谢人民邮电出版社授权并发编程网发表此文,版权所有,请勿转载.该书将于近期上市. 本章主要内容 何谓并发和多线程 为什么要在应用程序中使用并发和多线程 C++并发支持的发展历程 一个简单的C++多线程程序是什么样的 这是C++用户的振奋时刻.距1998年初始的C++标准发布13年后,C++标准委员会给予程序语言和它的支持库一次重大的变革.新的C++标

Java并发编程的艺术——互动出版网

这篇是计算机类的优质预售推荐>>>><Java并发编程的艺术> 阿里系和1号店资深技术专家撰写,Java并发编程领域的扛鼎之作,内容在InfoQ等社群得到高度认可,从JDK源码.JVM.CPU等多角度全面剖析与讲解Java并发编程的框架.原理和核心技术 编辑推荐 阿里系和1号店资深技术专家撰写,Java并发编程领域的扛鼎之作 内容在InfoQ等社群得到高度认可,从JDK源码.JVM.CPU等多角度全面剖析与讲解Java并发编程的框架.原理和核心技术 前言 为什么要写这本