我写了一个名为T的线程类。
我的目的是确保一次只有一个线程对象运行。
因此,当调用线程对象时,它会检查一个名为 BUSY 的布尔标志。
我的问题是
有什么不同private static AtomicBoolean BUSY = new AtomicBoolean(false);
和
private static boolean BUSY = false;
我认为如果使用“静态”,所有对象只会检查一个 BUSY 布尔变量,这样就可以确保只有一个线程对象正在运行。
您必须至少创建布尔变量
volatile
和 AtomicBoolean 变量 final
才能获得可比较的解决方案。执行此操作后,您的用例将不会有任何差异。
如果您使用
AtomicBoolean
的 getAndSet
或 compareAndSet
方法,则会出现差异,这些方法将一个读取和一个写入操作组合成一个原子整体,而当针对 volatile
完成时,这些操作不是原子的。
您可以使用
boolean
并通过适当的同步(并制作 volatile
)可以实现您所需要的。AtomicBoolean
,您可以原子地检查当前值,而无需自己编写同步代码
正如其他人所说,你必须分别将变量设置为final / volatile。
根据你的描述,我担心你有一个地方可以做这样的事情:
if (!BUSY){
BUSY = true;
}
请注意,在没有公共同步的情况下,这会被破坏,因为两个线程可能会检查该标志,都将其视为错误并开始工作。
我建议研究处理并发的现有结构:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html
特别是具有单一许可证的信号量可能就是您正在寻找的。
AtomicBoolean
的一个有用功能是当且仅当 BUSY 为 false 时允许单个线程继续,但不允许任何其他线程继续。
private static AtomicBoolean BUSY = new AtomicBoolean(false);
public void doWork(){
if(BUSY.compareAndSet(false,true)){
//do some work
BUSY.set(false);
}else{
//some other thread won, return now or retry later?
}
}
因此,在任何给定时间,只有一个线程会
doWork
。您无法使用 volatile boolean
实现此目的,因为您无法确定 Thread.currentThread()
是否设置了布尔值。