发生在线程和原子变量之间的第2部分

时间:2018-11-18 20:42:29

标签: java concurrency atomic volatile java.util.concurrent

由于对Happens before between threads and atomic variable的回答是断言不成立,因此我需要一个替代实现。线程1和线程2分别更新整数t1和t2。一旦更新,则不会对t1或t2进行其他任何更新。分配给t1和t2的值来自一个公共计数器,该计数器在每次分配后都会递增。我需要确保以下断言是正确的;

int cnt=0;
ReentrantLock lock = new ReentrantLock();
volatile Integer t1=null;
volatile Integer t2=null;

//Thread1
lock.lock();
try{t1=cnt++;}finally{lock.unlock();}
if(t2 == null){
  assert t2==null || t2>t1;
}

//Thread2
lock.lock();
try{t2=cnt++;}finally{lock.unlock();}
if(t1==null){
  assert t1==null || t1>t2;
}

问题是断言是否成立?如图所示,t1和t2上是否需要挥发物?有没有更好/正确的方法来实现这一目标?

2 个答案:

答案 0 :(得分:1)

  1. 是的,断言会过去。每次读写之间都有HB,并且可以保证,如果第一个线程被锁定,则第二个线程既不能递增计数器,也不能初始化其t变量。因此,如果线程位于if(t1==null){}中,则t2将是null或大于t1。另一个线程也是如此。
  2. 您无法从该代码中删除volatile,因为t1t2在不同线程之间共享,并且您需要确保在不同线程中该字段的读取和写入之间存在HB 。
  3. 如果存在更好的解决方案,恐怕我找不到这么快的解决方案。我认为任何可能进入if(t1==null){...}的正确解决方案都必须满足要求:t1=cnt++必须仅由一个线程同时执行。

答案 1 :(得分:-1)

如果(t1 == null)在到达相应的assert语句之前执行,则线程1在执行线程2之后有可能将线程1写入t1。

if语句并在其后声明应在同步上下文中执行。