Java:锁定线程时 AtomicBoolean 和静态布尔变量有什么不同?

问题描述 投票:0回答:4

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

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

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

我的问题是

有什么不同
private static AtomicBoolean BUSY = new AtomicBoolean(false);

private static boolean BUSY = false;

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

java multithreading synchronization thread-safety boolean
4个回答
8
投票

您必须至少创建布尔变量

volatile
和 AtomicBoolean 变量
final
才能获得可比较的解决方案。执行此操作后,您的用例将不会有任何差异。

如果您使用

AtomicBoolean
getAndSet
compareAndSet
方法,则会出现差异,这些方法将一个读取和一个写入操作组合成一个原子整体,而当针对
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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.