发生在线程和原子变量之间 [英] Happens before between threads and atomic variable

查看:58
本文介绍了发生在线程和原子变量之间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设一个AtomicInteger c在两个线程(线程1和线程2)之间共享. Thread1使用c.incrementAndGet()设置(仅一次)易失性变量t1. Thread2使用c.incrementAndGet()设置(仅一次)易失变量t2.一旦设置了t1和t2,就不会再由其他任何线程对其进行设置.假设线程1设置t1之后,它检查t2的值并获取null.是否保证随后将t2设置为比t1更高的值? (反之亦然).换句话说,下面的断言是否总是正确的?那是为什么呢?

Suppose an AtomicInteger,c, is shared between two threads, thread1 and thread2. Thread1 sets (one time only) a volatile variable t1 using c.incrementAndGet(). Thread2 sets (one time only) a volatile variable t2 using c.incrementAndGet(). Once t1 and t2 are set they are not set again by any other thread. Suppose that after thread1 sets t1, it checks the value of t2 and gets null. Is it guaranteed that t2 is subsequently set to a higher value then t1? (and visa versa). In other words are the assert below always true? Is so why?

AtomicInteger c = new AtomicInteger();
volatile Integer t1=null;
volatile Integer t2=null;

//Thread1
t1=c.incrementAndGet();
if(t2 == null){
  assert t2==null || t2>t1;
}

//Thread2
t2=c.incrementAndGet();
if(t1==null){
  assert t1==null || t1>t2;
}

我认为这些断言是正确的,原因如下:如果为t1分配了c的增量值,并且尚未为t2分配c的增量值,那么当随后为t2分配c的值时,t2必须为大于t1的值.

I believe the asserts are true for the following reason: If t1 is assigned a value from incrementing c and t2 has not yet been assigned a value by incrementing c then when t2 is subsequently assigned a value by incrementing c, it must be greater then the value of t1.

更新:由于根据断言下面的正确答案可能并不总是成立,因此我添加了第2部分的问题:请查看发生在线程和原子变量第2部分之间.

Update: Since as per the correct answer below the asserts may not always hold, I have added a part 2 question: Check out Happens before between threads and atomic variable Part 2.

推荐答案

不,不能保证.可能会发生以下情况:

No, there's no guarantee. The following could happen:

  • thread2:c.incrementAndGet(c为1,t2仍为null,但稍后将用1初始化)
  • thread1:c.incrementAndGet(c为2,t1仍为null,但稍后将用2初始化)
  • 线程1:t1 = 2
  • 线程1:如果(t2 == null):条件为true. if块被评估
  • 线程2:t2 = 1
  • thread1:t2 == null:条件为false,因此计算or的另一个操作数
  • 线程1:t2> t1:false,因为t2为1而t1为2
  • 线程1:断言:失败
  • thread2: c.incrementAndGet (c is 1, and t2 is still null, but will be initialized with 1 later)
  • thread1: c.incrementAndGet (c is 2, and t1 is still null, but will be initialized with 2 later)
  • thread1: t1 = 2
  • thread1: if (t2 == null): the condition is true. The if block is evaluated
  • thread2: t2 = 1
  • thread1: t2 == null: the condition is false, so the other operand of the or is evaluated
  • thread1: t2 > t1: false since t2 is 1 and t1 is 2
  • thread1: assert: fails

这篇关于发生在线程和原子变量之间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆