java原子操作
一、何谓Atomic?
Atomic一词跟原子有点关系,后者曾被人认为是最小物质的单位。计算机中的Atomic是指不能分割成若干部分的意思。如果一段代码被认为是Atomic,则表示这段代码在执行过程中,是不能被中断的。通常来说,原子指令由硬件提供,供软件来实现原子方法(某个线程进入该方法后,就不会被中断,直到其执行完成)
在x86 平台上,CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin,如果汇编语言的程序中在一条指令前面加上前缀"LOCK",经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持续到这条指令结束时放开,从而把总线锁住,这样同一总线上别的CPU就暂时不能通过总线访问内存了,保证了这条指令在多处理器环境中的原子性。
二、JDK1.5的原子包:java.util.concurrent.atomic
这个包里面提供了一组原子类。其基本的特性就是在多线程环境下,当有多个线程同时执行这些类的实例包含的方法时,具有排他性,即当某个线程进入方法,执行其中的指令时,不会被其他线程打断,而别的线程就像自旋锁一样,一直等到该方法执行完成,才由JVM从等待队列中选择一个另一个线程进入,这只是一种逻辑上的理解。实际上是借助硬件的相关指令来实现的,不会阻塞线程(synchronized 会把别的等待的线程挂起)(或者说只是在硬件级别上阻塞了)。
其中的类可以分成4组
- AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
- AtomicIntegerArray,AtomicLongArray
- AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
- AtomicMarkableReference,AtomicStampedReference,AtomicReferenceArray
Atomic类的作用
- 使得让对单一数据的操作,实现了原子化
- 使用Atomic类构建复杂的,无需阻塞的代码
- 访问对2个或2个以上的atomic变量(或者对单个atomic变量进行2次或2次以上的操作)通常认为是需要同步的,以达到让这些操作能被作为一个原子单元。
2.1 AtomicBoolean , AtomicInteger, AtomicLong, AtomicReference
这四种基本类型用来处理布尔,整数,长整数,对象四种数据。
- 构造函数(两个构造函数)
- 默认的构造函数:初始化的数据分别是false,0,0,null
- 带参构造函数:参数为初始化的数据
- set( )和get( )方法:可以原子地设定和获取atomic的数据。类似于volatile,保证数据会在主存中设置或读取
- getAndSet( )方法
- 原子的将变量设定为新数据,同时返回先前的旧数据
- 其本质是get( )操作,然后做set( )操作。尽管这2个操作都是atomic,但是他们合并在一起的时候,就不是atomic。在Java的源程序的级别上,如果不依赖synchronized的机制来完成这个工作,是不可能的。只有依靠native方法才可以。
- compareAndSet( ) 和weakCompareAndSet( )方法
- 这两个方法都是conditional modifier方法。这2个方法接受2个参数,一个是期望数据(expected),一个是新数据(new);如果atomic里面的数据和期望数据一致,则将新数据设定给atomic的数据,返回true,表明成功;否则就不设定,并返回false。
- 对于AtomicInteger、AtomicLong还提供了一些特别的方法。getAndIncrement( )、incrementAndGet( )、getAndDecrement( )、decrementAndGet ( )、addAndGet( )、getAndAdd( )以实现一些加法,减法原子操作。(注意 --i、++i不是原子操作,其中包含有3个操作步骤:第一步,读取i;第二步,加1或减1;第三步:写回内存)
2.1.1 1个例子-使用AtomicReference创建线程安全的堆栈
public class LinkedStack<T> {
private AtomicReference<Node<T>> stacks = new AtomicReference<Node<T>>();
public T push(T e) {
Node<T> oldNode, newNode;
while (true) { //这里的处理非常的特别,也是必须如此的。
oldNode = stacks.get();
newNode = new Node<T>(e, oldNode);
if (stacks.compareAndSet(oldNode, newNode)) {
return e;
}
}
}
public T pop() {
Node<T> oldNode, newNode;
while (true) {
oldNode = stacks.get();
newNode = oldNode.next;
if (stacks.compareAndSet(oldNode, newNode)) {
return oldNode.object;
}
}
}
private static final class Node<T> {
private T object;
private Node<T> next;
private Node(T object, Node<T> next) {
this.object = object;
this.next = next;
}
}
}
java原子操作的更多相关文章
- Java 并发系列之九:java 原子操作类Atomic(13个)
1. 原子更新基本类型类 2. 原子更新数组 3. 原子更新引用 4. 原子更新属性 5. txt java 原子操作类Atomic 概述 java.util.concurrent.atomic里的原 ...
- java原子操作的实现原理--转载
原文地址:http://www.infoq.com/cn/articles/atomic-operation 1. 引言 原子(atom)本意是“不能被进一步分割的最小粒子”,而原子操作(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 原子操作的实现原理[精品长文]
本文整理自<Java并发编程的艺术>第二章 作者:方腾飞 魏鹏 程晓明 原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为“不可被 ...
- Java原子操作类汇总(2)
当程序更新一个变量时,如果是多线程同时更新这个变量,可能得到的结果与期望值不同.比如:有一个变量i,A线程执行i+1,B线程也执行i+1,经过两个线程的操作后,变量i的值可能不是期望的3,而是2.这是 ...
- java 原子操作(1) CAS
在 java 多线程编程中经常说的就是:“原子操作(atomic operation) 不需要 synchronized”. 原子操作指的是不会被线程调度机制打断的操作:这种操作一旦开始,就一直运行到 ...
- java原子操作CAS
本次内容主要讲原子操作的概念.原子操作的实现方式.CAS的使用.原理.3大问题及其解决方案,最后还讲到了JDK中经常使用到的原子操作类. 1.什么是原子操作? 所谓原子操作是指不会被线程调度机制打断的 ...
随机推荐
- Swift基础之闭包Closure学习
首先Swift语言中没有了Block内容,但是你可以通过调用OC文件使用,也可以使用Closure(闭包),实现Block或者Delegae同样反向传值或回调函数的效果,也可以解决函数指针的问题,两者 ...
- SDL2源代码分析3:渲染器(SDL_Renderer)
===================================================== SDL源代码分析系列文章列表: SDL2源代码分析1:初始化(SDL_Init()) SDL ...
- 使用VideoView实现简单视频播放器
转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/39471397 VideoView内部封装好了Mediaplayer.Android框架 ...
- 四大组件之Activity小结
一大波面试就要靠近,赶紧总结总结一些基础问题 1.Activity的概念 是Android应用层开发的四大组件之一,主要负责和用户交互部分,有自己的生命周期,在其上可以布置按钮,文本框等各种控件,简单 ...
- Android进阶(五)在Eclipse中关联Gson源码
1)获得相应的jar包gson-2.2.4-sources.jar与gson-2.2.4-javadoc.jar. 2)在libs目录下新建src包和docs包,将相应jar包放入相应文件夹内. 3) ...
- React 之props属性
React 里有一个非常常用的模式就是对组件做一层抽象.组件对外公开一个简单的属性(Props)来实现功能,但内部细节可能有非常复杂的实现. 可以使用 JSX 展开属性 来合并现有的 props 和其 ...
- CUDA学习,查看device性能参数
#include "../common/book.h" #include< stdio.h> #include "cuda_runtime.h" # ...
- 内存数据网格hazelcast的一些机制原理
hazelcast作为一个内存数据网格工具,还算比较优秀,听说有Apache顶级项目使用它,值得研究下,使用文档可以直接看官方文档,但机制原理相关的资料基本没有,本人硬撸源码写的一些东西,跟大家分享一 ...
- C++中不能被重载的运算符介绍
C/C++ 里大多数运算符都可以在 C++ 中被重载. C 的运算符中只有 . 和 ?:(以及 sizeof,技术上可以看作一个运算符)不可以被重载.C++ 增加了一些自己的运算符,除了 :: 和 . ...
- 【64】Spring mvc详解
Spring mvc框架 Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活.松散耦合的 web 应用程序的组件.MVC 模式导致了应用程序的不同方面(输入逻辑.业务 ...