我什么时候需要在Java中使用AtomicBoolean?
我怎样才能使用AtomicBoolean和那个类是什么?
当多个线程需要检查并更改布尔值时。 例如:
if (!initialized) { initialize(); initialized = true; }
这不是线程安全的。 你可以通过使用AtomicBoolean
来修复它:
if (atomicInitialized.compareAndSet(false, true)) { initialize(); }
这里是笔记( 来自Brian Goetz的书)我做的可能对你有帮助
AtomicXXX类
-
提供非阻塞比较和交换实现
-
利用硬件提供的支持(英特尔的CMPXCHG指令)当使用这些primefaces并发API的代码运行大量线程时,它们将比使用对象级别监视器/同步的代码好得多。 由于Java的同步机制使代码等待,当有很multithreading通过关键部分运行时,大量CPU时间花费在pipe理同步机制本身(等待,通知等)上。 由于新的API使用硬件级构造(primefacesvariables)并等待和locking自由algorithm来实现线程安全性,所以更多的CPU时间花在“做事”上,而不是pipe理同步。
-
不仅提供了更好的吞吐量,而且还对死锁和优先级反转等活性问题提供了更大的阻力。
有两个主要原因可以使用primefaces布尔值。 首先它是可变的,你可以把它作为一个引用来传递,例如改变一个与布尔本身相关的值。
public final class MyThreadSafeClass{ private AtomicBoolean myBoolean = new AtomicBoolean(false); private SomeThreadSafeObject someObject = new SomeThreadSafeObject(); public boolean doSomething(){ someObject.doSomeWork(myBoolean); return myBoolean.get(); //will return true } }
和someObject类中
public final class SomeThreadSafeObject{ public void doSomeWork(AtomicBoolean b){ b.set(true); } }
更重要的是,它的线程是安全的,可以向开发人员维护这个类,这个variables有望被修改并从多个线程中读取。 如果你不使用AtomicBoolean,你必须通过声明它的variables或同步字段的读写同步你正在使用的布尔variables。
AtomicBoolean
类为您提供一个布尔值,您可以自动更新。 当你有多个线程访问一个布尔variables时使用它。
java.util.concurrent.atomic包概述为您提供了一个很好的关于这个包中的类是什么以及何时使用它们的高级描述。 我还推荐Brian Goetz编写的Java Concurrency in Practice一书。
摘录自软件包描述
软件包java.util.concurrent.atomic描述:一个支持单variables无锁线程安全编程的小型工具包。
这些方法的规范使得实现能够采用在当代处理器上可用的高效的机器级primefaces指令。
类AtomicBoolean,AtomicInteger,AtomicLong和AtomicReference中的每个实例都提供对相应types的单个variables的访问和更新[…]。
对于访问和更新primefaces的记忆效应一般遵循挥发物的规则:
- 获得读取volatilevariables的记忆效应。
- 集具有写入(分配)易失性variables的记忆效应。
- weakCompareAndSet自动读取并有条件地写入一个variables,相对于该variables上的其他存储器操作被sorting,但除此之外,其作为普通的非易失性存储器操作。
- compareAndSet和所有其他读取和更新操作(如getAndIncrement)具有读取和写入易失性variables的内存效果。