5

我编写了一个名为 T 的线程类。

我的目的是确保一次只运行一个线程对象。

因此,当调用线程对象时,它会检查一个名为 BUSY 的布尔标志。

我的问题是有什么不同

private static AtomicBoolean BUSY = new AtomicBoolean(false);

private static boolean BUSY = false;

我想如果使用“静态”,所有对象只会检查一个 BUSY 布尔变量,这样可以确保只有一个线程对象在运行。

4

4 回答 4

8

您必须至少创建布尔变量volatile和 AtomicBoolean 变量final才能获得可比较的解决方案。在你这样做之后,你的用例将没有什么不同。

如果您使用AtomicBoolean'sgetAndSetcompareAndSet方法,则会出现差异,它们将一个读取和一个写入操作组合成一个原子整体,而当针对volatile.

于 2012-08-20T09:29:12.257 回答
2

您可以使用booleanand 与适当的同步(和制作volatile)可以实现您所需要的。
但是通过使用,AtomicBoolean您可以原子地检查当前值,而无需自己编写代码进行同步

于 2012-08-20T09:43:29.227 回答
0

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

根据你的描述,我担心你有一个地方可以做这样的事情:

if (!BUSY){
    BUSY = true;
}

请注意,这在没有公共同步的情况下会被破坏,因为两个线程可能会检查该标志,都将其视为错误并开始工作。

我建议研究处理并发的现有结构:http: //docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html

特别是具有单一许可证的信号量可能是您正在寻找的。

于 2012-08-20T10:09:06.513 回答
0

an 的一个有用特性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在任何给定时间,这里只有一个线程。你不能用 a 来实现这一点,volatile boolean因为你不能确定Thread.currentThread()设置布尔值。

于 2012-08-20T20:54:38.677 回答