竞态条件“签入当时的行为”和“读 - 修改 - 写”(Race conditions “check-

2019-07-02 12:47发布

任何人都可以给我解释一下什么是竞争条件,如何避免它,以及如何找到它在Java代码?

好吧,我只知道“竞态条件”好几天了,我有两个例子,也许他们还不够好,这就是为什么我需要你的帮助:)希望你们中的任何可以解释我。

例1:检查然后采取行动:

if(vector.contains(e))//check
{
vector.remove(e)
}

如果有2个线程可以访问,线程1暂停之后检查向量包含E,和E确实在载体中,然后线程2进入检查,然后从载体除去e,然后线程1回来,做删除操作,将出现错误,因为e是已经被删除线程2。

例2:读 - 修改 - 写:

假设我们有一个计数器变量的方法,一旦该方法被调用时,计数器增加1,

counter++

这不是一个原子操作,它有3个步骤:1.获得值2增加值3分配给值

我所知道的关于种族的条件都在这里,希望你能与我分享你的知识:)

谢谢

Answer 1:

什么是竞争状态? 检查这个堆栈溢出问题 。

主要有两种情景竞争条件:读 - 修改 - 写检查,当时的行为。

对于读-修改-写的经典例子是counter++这不是一个原子操作,从而导致了竞争条件。

对于检查当时的行为有多个实例。 一个例子是,当您为您在ConcurrentHashMap中存在的关键,然后做如果情况做一些工作。 另一个例子是单例类代码:

public Singleton getInstance()
{
   if(_instance == null)
   { 
      _instance = new Singleton();
   }
}

你可以阅读更多关于他们的互联网上。 一本好书并发的Java并发实践Brian Goetz撰写。 您还可以找到这个文章有帮助。



Answer 2:

从Java并发编程实践本书

“当计算的正确性取决于相对定时或由运行时的多个线程的交错时,发生争用条件;换句话说,得到了正确的答案时依赖于幸运定时”

竞争状态最常见的情况是检查当时的行为,其中一个潜在的安全观察是用来做什么做下一个决定。

竞争状态另一种常见的情况,如果放缺席

对于示例1。

 if (!vector.contains(element))
   vector.add(element);

这种尝试在看跌期权,如果非存在操作有竞争状态,即使含有和添加是原子。 虽然同步方法可以使各个操作原子,额外的锁定需要 - 当多个操作被组合成复合动作。



Answer 3:

在回答中提供的示例:“读-修改-写入”和“检查当时的行为”都不足以定义的竞争条件的情况下。

如果你理解了“竞态条件”在不确定的顺序访问共享内存引起的两个或多个线程不可预知结果的情况下,其中至少一个访问是写,然后(一)你不需要同时拥有“读”在同一个线程和“写”。

(b)可变的原子定义不从比赛条件的潜在拯救我们,无论是。 如果一个线程的其他线程从中读取和访问没有正确排序前后写入原子变量,结果仍然是不可预知的。 你可以看到这一点的进一步解释这里 。



文章来源: Race conditions “check-then-act” and “read-modify-write”