(转)Java并发包:AtomicBoolean和AtomicReference

转:https://blog.csdn.net/zxc123e/article/details/52057289

文章译自:http://tutorials.jenkov.com/java-util-concurrent/index.html
这个系列文章已基本结束,如有不妥,请批评指正。
转自请注明出处。

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();

这个例子创建了一个AtomicBoolean默认值为false。

如果你需要显示的设置AtomicBoolean的初始值,你可以给AtomicBoolean传递一个初始值。

AtomicBoolean atomicBoolean = new AtomicBoolean(true);
  • 获取AtomicBoolean的值

你可以使用get()方法获取AtomicBoolean的值,下面是一个例子:

AtomicBoolean atomicBoolean = new AtomicBoolean(true);

boolean value = atomicBoolean.get();

执行上面的代码后value变量的值将为ture。

  • 设置AtomicBoolean的值

你可以使用set()方法设置AtomicBoolean的值,下面是一个例子:

AtomicBoolean atomicBoolean = new AtomicBoolean(true);

atomicBoolean.set(false);

执行上面的代码后atomicBoolean 变量的值将为false。

  • 交换AtomicBoolean的值。

你可以使用getAndSet()交换AtomicBoolean的值。getAndSet()方法返回AtomicBoolean当前的值,并给它设置一个新的值。下面是一个例子:

AtomicBoolean atomicBoolean = new AtomicBoolean(true);

boolean oldValue = atomicBoolean.getAndSet(false);

执行上面的代码后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);

这个例子中把AtomicBoolean的当前值和true做对比,如果两个值相等,将会给AtomicBoolean设置一个新值false。

AtomicReference

AtomicReference类提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。AtomicReferenc的compareAndSet()方法可以使得它与期望的一个值进行比较,如果他们是相等的,AtomicReference里的对象会被设置成一个新的引用。

创建AtomicReference

你可以下面这样创建一个AtomicReference的实例。

AtomicReference atomicReference = new AtomicReference();

如果你需要使用一个初始引用来创建AtomicReference,你可以像下面这样做。

String initialReference = "the initially referenced string";
AtomicReference atomicReference = new AtomicReference(initialReference);
  • 创建泛型AtomicReference

你可以使用java泛型创建一个类型化的AtomicReference。下面是一个例子:

AtomicReference<String> atomicStringReference =
    new AtomicReference<String>();

你也可以给类型化的AtomicReference指定初始值,下面是给类型化的AtomicReference指定初始值的例子:

String initialReference = "the initially referenced string";
AtomicReference<String> atomicStringReference =
    new AtomicReference<String>(initialReference);

获得AtomicReference引用

你可以使用AtomicReference的get()方法获的存储在AtomicReference中的引用。如果你在非泛型化的AtomicReference上使用get()方法将会返回一个Object引用。如果在泛型化的AtomicReference上使用get()方法将会返回你在AtomicReference上声明的类型的引用。

下面是一个非泛型化的AtomicReference的get()的例子:

AtomicReference atomicReference = new AtomicReference("first value referenced");

String reference = (String) atomicReference.get();

注意,当AtomicReference是一个非泛型化的时,必须将get()方法返回的引用强制转换为String,因为get()放好的是一个Object引用。

下面是一个泛型化的AtomicReference的例子:

AtomicReference<String> atomicReference =
     new AtomicReference<String>("first value referenced");

String reference = atomicReference.get();

注意,这里不需要将get()返回的引用进行强制转换,因为编译器知道它返回一个String引用。

设置AtomicReference引用

你可以使用set()方法设置储存在AtomicReferenc实例中的引用。对于非泛型化的AtomicReference的实例,set()方法会将一个Object引用作为参数。对于泛型化的AtomicReference,set()方法将使用你在AtmoicReference上声明的类型的引用作为参数。

下面是一个AtomicReference的set()的例子:

AtomicReference atomicReference =
     new AtomicReference();

atomicReference.set("New object referenced");

对于泛型和非泛型的引用在使用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);

上面的例子中使用了一个初始的引用创建了一个泛型化的AtomicReference。然后调用两次compareAndSet()方法来比较储存的引用和初始的引用。如果储存的引用与初始引用是相等的将会设置一个新的引用。第一次的时候两个引用是相等的,因此AtomicReference被设置了一个新的引用。第二次储存的引用是之前调用compareAndSet()放新设置的引用,因此储存的引用一定是与初始的引用是不相等的。于是,AtomicReference不会被设置成一个新的引用,compareAndSet()方法返回false。

原文地址:https://www.cnblogs.com/wangle1001986/p/9313893.html

时间: 2024-10-15 00:28:50

(转)Java并发包:AtomicBoolean和AtomicReference的相关文章

【java基础】Java并发包

Java并发包 一.并发包的结构 java并发包中共分为五类: 1.集合框架:包括队列和并发集合 2.同步辅助类 3.线程池 4.Lock锁 5.原子类 二.详解部分 1.同步辅助类详解部分 (1)CountDownLatch 举例:有三个工作,只有三个工作都完成,任务才算执行完成. 1 import java.util.concurrent.CountDownLatch; 2 3 /** 4 * 5 * @author qiuxiang 6 * 7 */ 8 public class Coun

Java并发包总结

Java 并发包 并发包中除了提供高性能的线程安全的集合对象外,还提供了很多并发场景需要的原子操作类,例如AtomicInteger,另外还提供了一些用于避免并发时资源冲突的Lock及Condition类. ConcurrentHashMap 线程安全的HashMap的实现. 维护的是一个Segment对象数组,segment继承ReentrantLock 方法 意义 ConcurrentHashMap() put(Object key,Object value) ConcurrentHashM

Java并发包——Blockingqueue,ConcurrentLinkedQueue,Executors

背景 通过做以下一个小的接口系统gate,了解一下mina和java并发包里的东西.A系统为javaweb项目,B为C语言项目,gate是本篇须要完毕的系统. 需求 1. A为集群系统,并发较高,会批量发送给gate消息,而且接受gate返回的消息. 2. gate独立部署,将从A接受到的消息压入队列,与B建立连接后,将每条消息验证签名等工作后,发送给B.须要保证性能: 3. B负责处理消息,并返回处理结果,B为gate提供提供六个port,一个port可有三个长连接(须由gate发送心跳保持长

Java并发包源码学习之AQS框架(一)概述

AQS其实就是java.util.concurrent.locks.AbstractQueuedSynchronizer这个类. 阅读Java的并发包源码你会发现这个类是整个java.util.concurrent的核心之一,也可以说是阅读整个并发包源码的一个突破口. 比如读ReentrantLock的源码你会发现其核心是它的一个内部类Sync: 整个包中很多类的结构都是如此,比如Semaphore,CountDownLatch都有一个内部类Sync,而所有的Sync都是继承自AbstractQ

java并发包小结(二)

接上一篇 java并发包小结(一):http://blog.csdn.net/aalansehaiyang52/article/details/8877579 Future 接口Future 接口允许表示已经完成的任务.正在执行过程中的任务或者尚未开始执行的任务.通过 Future 接口,可以尝试取消尚未完成的任务,查询任务已经完成还是取消了,以及提取(或等待)任务的结果值.FutureTask 类实现了 Future,并包含一些构造函数,允许将 Runnable 或 Callable(会产生结

java并发包小结(一)

java.util.concurrent 包含许多线程安全.高性能的并发构建块.换句话讲,创建 java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作.通过提供一组可靠的.高性能并发构建块,开发人员可以提高并发类的线程安全.可伸缩性.性能.可读性和可靠性. JDK 5.0 中的并发改进可以分为三组:    1. JVM 级别更改.大多数现代处理器对并发对某一硬件级别提供支持,通常以 compare-and-swap (CAS)指令形式.C

深入浅出Java并发包—锁机制(三)

接上文<深入浅出Java并发包—锁机制(二)>  由锁衍生的下一个对象是条件变量,这个对象的存在很大程度上是为了解决Object.wait/notify/notifyAll难以使用的问题. 条件(也称为条件队列 或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为 true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”).因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联.等待提供一个条件的主要属性是:以原子方式 释放相关的锁,并

深入浅出Java并发包—锁机制(二)

接上文<深入浅出Java并发包—锁机制(一)  >  2.Sync.FairSync.TryAcquire(公平锁) 我们直接来看代码 protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (isFirst(current) && compareAndSetStat

java并发包研究之-ConcurrentHashMap

概述 HashMap是非线程安全的,HashTable是线程安全的. 那个时候没怎么写Java代码,所以根本就没有听说过ConcurrentHashMap,只知道面试的时候就记住这句话就行了…至于为什么是线程安全的,内部怎么实现的,通通不了解. 今天我们将深入剖析一个比HashTable性能更优的线程安全的Map类,它就是ConcurrentHashMap,本文基于Java 7的源码做剖析. ConcurrentHashMap的目的 多线程环境下,使用Hashmap进行put操作会引起死循环,导

使用Java并发包线程池和XML实现定时任务动态配置和管理

文章标题:使用并发包线程池和XML实现定时任务动态配置和管理 文章地址: http://blog.csdn.net/5iasp/article/details/32705601 作者: javaboy2012Email:[email protected]qq:    1046011462 项目结构: 一.采用的知识点: 1. java并发包2. xml配置文件读取3. 反射动态调用类的方法 二. 基本思路 1.  创建线程池: ScheduledExecutorService scheduExe