加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 线程安全否定AtomicBoolean get()作为while循环中的条件

发布时间:2020-12-15 04:40:14 所属栏目:Java 来源:网络整理
导读:假设我有以下代码: AtomicBoolean condition;condition = new AtomicBoolean(false);(...)while(!condition.get()){ // do some stuff} 我知道condition.get()是atomic,但是,还是!condition.get()原子? 我的意思是,如果一个Thread以原子方式读取布尔值,然
假设我有以下代码:

AtomicBoolean condition;
condition = new AtomicBoolean(false);
(...)
while(!condition.get()){
   // do some stuff
}

我知道condition.get()是atomic,但是,还是!condition.get()原子?

我的意思是,如果一个Thread以原子方式读取布尔值,然后在应用之前中断它就会发生!操作,以便另一个Thread进入循环之前?如果是这种情况,使用如下函数会更好吗:

private synchronized boolean checkNegatedCondition(AtomicBoolean cond){
    return !cond.get();
}

(...)

while(checkNegatedCondition(condition)){
   // do some stuff
}

提前致谢.

解决方法

原子性不是问题.
两个线程可以同时读取原子变量.
因此,任何数量的线程都可以读取该值并根据其否定进入循环.如果没关系!是原子的.它作用于线程本地值.

要使用原子进行排除,通常需要AtomicBoolean.compareAndSet(boolean,boolean).

v.compareAndSet(a,b)只会将v设置为值b,如果它是a并返回true.否则如果v在开始时没有值a,则它什么都不做并返回false.

在伪代码中它是

synchronized public boolean compareAndSet(boolean a,boolean b){
      if(v!=a) return false;
      v=b;
      return true;
 }

但是(非常重要)以原子方式进行,因此v上的所有其他操作可以在它之前或之后进行排序.

AtomicBoolean condition = new AtomicBoolean(false);
//...
if(condition.compareAndSet(false,true)){
   //Only one thread can get here unless condition is set back...
}

如果你想将它用作’伪’同步块,你可能会编码:

while(!condition.compareAndSet(false,true));
   //Only one thread can get here at a time...
 condition.set(false);

这可以被描述为’锁定’.因为线程’等待’进入受控部分’旋转’在循环中四舍五入直到释放.
这可能表现出比同步更差的性能,因为该操作系统通常会“暂停”等待线程并执行其他任务.
然而,在争用非常低的情况下(即,需要很少或不需要等待),自旋锁可以表现出更好的性能.

专业提示:在实践中,最好将condition.set(false)放在最后的块中:

while(!condition.compareAndSet(false,true));
try {
   //Only one thread can get here at a time...
 }finally{
     condition.set(false);
 }

否则,在一个线程中抛出的异常将永久锁定对该部分代码的任何访问.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读