Java:当锁定线程时,AtomicBoolean 和静态布尔变量有什么区别?

5
我写了一个名为T的线程类。
我的目的是确保同一时间只有一个线程对象在运行。
因此,当调用线程对象时,它会检查一个名为BUSY的布尔标志。
我的问题是,

之间有什么不同?

private static AtomicBoolean BUSY = new AtomicBoolean(false);

并且

private static boolean BUSY = false;

我认为,如果使用“static”,所有对象都只会检查一个BUSY布尔变量,这样可以确保只有一个线程对象在运行。
4个回答

8
你必须至少将布尔变量volatile和AtomicBoolean变量final,以便获得可比较的解决方案。在你这样做之后,对于你的使用情况来说就没有区别了。
如果你使用AtomicBooleangetAndSetcompareAndSet方法,会有所不同,因为它们将读取和写入操作组合成一个原子整体,而当针对volatile执行时,这些操作并不是原子的。

2

您可以使用boolean,通过适当的同步(并使其volatile)来实现所需的功能。
但是,使用AtomicBoolean,您可以原子地检查当前值,无需编写自己的同步代码。


0

正如其他人所说,您必须分别将变量设置为final/volatile。

根据您的描述,我担心您可能有一个地方在那里您做了类似这样的事情:

if (!BUSY){
    BUSY = true;
}

请注意,在没有共同的同步机制的情况下,这段代码可能会出现问题。因为两个线程可能会同时检查标志位,都认为它是假的并开始执行工作。
我建议您研究一下处理并发的现有结构:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html 特别是使用单个许可的Semaphore可能是您需要的解决方案。

0

AtomicBoolean 一个有用的特性是允许单个线程继续运行,当且仅当BUSY为假但不会让任何其他线程继续运行。

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()是否设置了布尔值。


我建议在 finally 中执行 BUSY.set(false),以确保它真正被执行。 - Harald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接