Java并发包:AtomicBoolean和AtomicReference
AtomicBoolean
AtomicBoolean是一个读和写都是原子性的boolean类型的变量。这里包含高级的原子操作,例如compareAndSet()。AtomicBoolean位于Java.util.concurrent.atomic包中,因此全类名是java.util.concurrent.atomic.AtomicBoolean。这篇文章讲述的AtomicBoolean的版本可以在java 8中找到,第一个版本在java 5中增加。
AtomicBoolean设计背后的原理在我的另一篇文章Compare and Swap有解释。
创建AtomicBoolean
你可以像下面一样创建一个AtomicBoolean:
AtomicBoolean atomicBoolean = new AtomicBoolean();
- 1
这个例子创建了一个AtomicBoolean默认值为false。
如果你需要显示的设置AtomicBoolean的初始值,你可以给AtomicBoolean传递一个初始值。
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
- 1
- 获取AtomicBoolean的值
你可以使用get()方法获取AtomicBoolean的值,下面是一个例子:
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
boolean value = atomicBoolean.get();
- 1
- 2
- 3
执行上面的代码后value变量的值将为ture。
- 设置AtomicBoolean的值
你可以使用set()方法设置AtomicBoolean的值,下面是一个例子:
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
atomicBoolean.set(false);
- 1
- 2
- 3
执行上面的代码后atomicBoolean 变量的值将为false。
- 交换AtomicBoolean的值。
你可以使用getAndSet()交换AtomicBoolean的值。getAndSet()方法返回AtomicBoolean当前的值,并给它设置一个新的值。下面是一个例子:
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
boolean oldValue = atomicBoolean.getAndSet(false);
- 1
- 2
- 3
执行上面的代码后oldValue的值为true,AtomicBoolean实例的值为false.代码有效的交换了当前值为true的AtomicBoolean值使之为false。
- 比较和设置AtomicBoolean的值
compareAndSet()可以使AtomicBoolean的当前值和你期望的值作对比。如果当前值就是你期望的值,一个新的值会在AtomicBoolean上设置。compareAndSet()方法是原子的,因此,同一时刻仅允许一个线程执行它。于是,compareAndSet()方法可以用于实现简单的同步器例如锁。
下面是使用compareAndSet()的例子:
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
boolean expectedValue = true;
boolean newValue = false;
boolean wasNewValueSet = atomicBoolean.compareAndSet(
expectedValue, newValue);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这个例子中把AtomicBoolean的当前值和true做对比,如果两个值相等,将会给AtomicBoolean设置一个新值false。
AtomicReference
AtomicReference类提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。AtomicReferenc的compareAndSet()方法可以使得它与期望的一个值进行比较,如果他们是相等的,AtomicReference里的对象会被设置成一个新的引用。
创建AtomicReference
你可以下面这样创建一个AtomicReference的实例。
AtomicReference atomicReference = new AtomicReference();
- 1
如果你需要使用一个初始引用来创建AtomicReference,你可以像下面这样做。
String initialReference = "the initially referenced string";
AtomicReference atomicReference = new AtomicReference(initialReference);
- 1
- 2
- 创建泛型AtomicReference
你可以使用java泛型创建一个类型化的AtomicReference。下面是一个例子:
AtomicReference<String> atomicStringReference =
new AtomicReference<String>();
- 1
- 2
你也可以给类型化的AtomicReference指定初始值,下面是给类型化的AtomicReference指定初始值的例子:
String initialReference = "the initially referenced string";
AtomicReference<String> atomicStringReference =
new AtomicReference<String>(initialReference);
- 1
- 2
- 3
获得AtomicReference引用
你可以使用AtomicReference的get()方法获的存储在AtomicReference中的引用。如果你在非泛型化的AtomicReference上使用get()方法将会返回一个Object引用。如果在泛型化的AtomicReference上使用get()方法将会返回你在AtomicReference上声明的类型的引用。
下面是一个非泛型化的AtomicReference的get()的例子:
AtomicReference atomicReference = new AtomicReference("first value referenced");
String reference = (String) atomicReference.get();
- 1
- 2
- 3
注意,当AtomicReference是一个非泛型化的时,必须将get()方法返回的引用强制转换为String,因为get()放好的是一个Object引用。
下面是一个泛型化的AtomicReference的例子:
AtomicReference<String> atomicReference =
new AtomicReference<String>("first value referenced");
String reference = atomicReference.get();
- 1
- 2
- 3
- 4
注意,这里不需要将get()返回的引用进行强制转换,因为编译器知道它返回一个String引用。
设置AtomicReference引用
你可以使用set()方法设置储存在AtomicReferenc实例中的引用。对于非泛型化的AtomicReference的实例,set()方法会将一个Object引用作为参数。对于泛型化的AtomicReference,set()方法将使用你在AtmoicReference上声明的类型的引用作为参数。
下面是一个AtomicReference的set()的例子:
AtomicReference atomicReference =
new AtomicReference();
atomicReference.set("New object referenced");
- 1
- 2
- 3
- 4
对于泛型和非泛型的引用在使用set()上看起并没有什么不同。唯一的不同是编译器会对泛型的AtomicReference有类型约束。
比较和设置AtomicReference引用
AtomicReference有一个非常有用的方法是compareAndSet()。compareAndSet()方法可以将存储在AtomicReference中的引用同你的预期值做一个比较,如果他们是相同的(not equal as in equals() but same as in ==),那么在AtomicReference实例上会设置一个新的引用。
如果compareAndSet()方法给AtomicReference设置了新的引用,它会返回true。否则会返回false。
下面是AtomicReference compareAndSet()方法的例子:
String initialReference = "initial value referenced";
AtomicReference<String> atomicStringReference =
new AtomicReference<String>(initialReference);
String newReference = "new value referenced";
boolean exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
System.out.println("exchanged: " + exchanged);
exchanged = atomicStringReference.compareAndSet(initialReference, newReference);
System.out.println("exchanged: " + exchanged);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
上面的例子中使用了一个初始的引用创建了一个泛型化的AtomicReference。然后调用两次compareAndSet()方法来比较储存的引用和初始的引用。如果储存的引用与初始引用是相等的将会设置一个新的引用。第一次的时候两个引用是相等的,因此AtomicReference被设置了一个新的引用。第二次储存的引用是之前调用compareAndSet()放新设置的引用,因此储存的引用一定是与初始的引用是不相等的。于是,AtomicReference不会被设置成一个新的引用,compareAndSet()方法返回false。
Java并发包:AtomicBoolean和AtomicReference的更多相关文章
- 深入浅出Java并发包—原子类操作
我们知道,JDK1.5以后引入了并发包(java.util.concurrent)用于解决多CPU时代的并发问题,而并发包中的类大部分是基于Queue的并发类,Queue在大多数情况下使用了原子类(A ...
- Java并发包——Atomic操作
Java并发包——Atomic操作 摘要:本文主要学习了Java并发包下的atomic包中有关原子操作的一些类. 部分内容来自以下博客: https://blog.csdn.net/qq_303796 ...
- Java并发包中常用类小结(一)
从JDK1.5以后,Java为我们引入了一个并发包,用于解决实际开发中经常用到的并发问题,那我们今天就来简单看一下相关的一些常见类的使用情况. 1.ConcurrentHashMap Concurre ...
- 对着java并发包写.net并发包之原子类型实现
众所周知,java1.5并发包通过volatile+CAS原理提供了优雅的并发支持.今天仔细想想.net也有volatile关键字保证内存的可见性,同时也有Interlocked提供了CAS的API, ...
- 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...
- Java并发包
刚看到一篇总结的比较全的JUC包总结,转载如下: 1. java.util.concurrent - Java 并发工具包 Java 5 添加了一个新的包到 Java 平台,java.util.con ...
- Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理
Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...
- Java并发包源码学习系列:挂起与唤醒线程LockSupport工具类
目录 LockSupport概述 park与unpark相关方法 中断演示 blocker的作用 测试无blocker 测试带blocker JDK提供的demo 总结 参考阅读 系列传送门: Jav ...
- Java并发包源码学习之AQS框架(四)AbstractQueuedSynchronizer源码分析
经过前面几篇文章的铺垫,今天我们终于要看看AQS的庐山真面目了,建议第一次看AbstractQueuedSynchronizer 类源码的朋友可以先看下我前面几篇文章: <Java并发包源码学习 ...
- Java并发包源码学习之AQS框架(三)LockSupport和interrupt
接着上一篇文章今天我们来介绍下LockSupport和Java中线程的中断(interrupt). 其实除了LockSupport,Java之初就有Object对象的wait和notify方法可以实现 ...
随机推荐
- ES5 object方法整理
Object.getPrototypeOf(object):调用对象父类原型上的方法; function Person(){ this.method1 = function(){alert(1)} } ...
- img 加载网络图片失败 显示默认图片
1. 概述 当从网络加载图片失败 希望显示默认图 img 标签有个 onerror属性 2. 代码 2.1 java服务端组织标签整个返回前端 String imgUrl = "javasc ...
- HighChart利用servlet导出中文PNG图片乱码问题解决
最近用到HighChart作图,在图片导出时,出现了图片中中文乱码的问题,在网络上找了很多资料,但都没有解决,最后才发现了最容易被忽略的问题.具体见下. 由于之前有同事使用过HighChart,所以毫 ...
- Vs2013 & .net framework 4.5.1 预览介绍
微软发布了vs2013 preview 和fw4.5.1 下面简单介绍一下与大家共享 Developer productivity X64 edit and continue 在2013里面 可以在x ...
- 如何判断单链表是否存在环 & 判断两链表是否相交
给定一个单链表,只给出头指针h: 1.如何判断是否存在环? 2.如何知道环的长度? 3.如何找出环的连接点在哪里? 4.带环链表的长度是多少? 解法: 1.对于问题1,使用追赶的方法,设定两个指针sl ...
- C++的extern关键字
extern是一个声明,不是一个定义,A模块想应用B模块的一个函数或者变量,A模块包含B模块的头文件,并且在变量或者头文件前,加 extern,虽然编译的时候,找不到模块的定义,但是在连接的时候,会在 ...
- July 14th 2017 Week 28th Friday
A life without a dress rehearsal, every day is broadcast live. 人生没有彩排,每天都是现场直播. Every day when I pre ...
- su
参数选项:-,-l,--login 切换用户的同时,将用户的家目录.系统环境变量等重新按切换后的用户初始化.-c 向shell传递单个命令,仅希望在某个用户下执行命令,而不用直接切换到该用户下来操作. ...
- Django 玩转API
现在,让我们进入Python的交互式shell,玩转这些Django提供给你的API. 使用如下命令来调用Python shell: $ python manage.py shell 我们使用上述命令 ...
- 绘图、Core Animation与硬件架构
原文地址:http://blog.csdn.net/wzzvictory/article/details/11180241 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号wan ...