我经常发现并发编程的情况下使用这些术语。 他们是同一事物或不同?
Answer 1:
不,他们是不一样的东西。 他们不是彼此的子集。 他们也没有必要,也没有对彼此的充分条件。
数据竞争的定义是很清楚的,因此,它的发现可以实现自动化。 当来自不同线程2个指令访问相同的存储位置时,会发生数据种族,这些访问中的至少一个是写入和没有同步被强制这些访问中的任何特定顺序。
竞争状态是一个语义错误。 这是发生在时间或事件导致错误的程序行为的顺序一个缺陷。 许多比赛条件可以通过数据竞争引起的,但是这是没有必要的。
考虑下面的简单的例子,其中x是一个共享的变量:
Thread 1 Thread 2
lock(l) lock(l)
x=1 x=2
unlock(l) unlock(l)
在这个例子中,从线程1和2中的写X是由锁保护,因此它们总是以某种顺序由与该锁在运行时获取的顺序执行发生。 也就是说,写原子不能被打破; 总会有任何执行两个写入之间的关系之前发生。 我们只是不知道哪写之前,其他先天发生的。
还有就是写之间没有固定的顺序,因为锁不能提供这一点。 如果计划的正确性就会大打折扣,说什么时候接着是写在线程1个由线程2 x的写,我们说有一个竞争条件,虽然在技术上不存在数据竞争。
这是更为有用的检测竞态条件比数据争; 然而,这也很难实现。
构建反向示例也是微不足道的。 该博客文章还解释了区别非常好,用一个简单的银行交易的例子。
Answer 2:
根据维基百科,术语“竞态条件”一直沿用至今的第一电子逻辑门的日子。 在Java的情况下,竞争条件可以涉及任何资源,如文件,网络连接,从线程池中的线程,等等。
术语“数据争”最好是由定义其特定的含义保留JLS 。
最有趣的案例是一个竞争条件,这是非常类似的数据比赛,但还不是一个,就像在这个简单的例子:
class Race {
static volatile int i;
static int uniqueInt() { return i++; }
}
由于i
是挥发性的,没有数据的比赛; 然而,从程序正确性的观点来看是有竞争条件,由于两个操作的非原子:读i
,写i+1
。 多个线程可以接收来自相同的值uniqueInt
。
Answer 3:
不,他们是不同的-他们都不是一个反之亦然的一个子集 。
术语竞争条件经常混淆与所述相关项数据争用,当同步未用于协调所有访问共享非最终字段它产生。 每当一个线程写入,可能下一个被另一个线程读取或读取可能最后写了由如果两个线程不使用同步另一个线程变量的变量,你的风险数据竞争; 与数据争码具有下Java内存模型没有有用的定义的语义。 并非所有的比赛条件是数据的比赛,而不是所有的数据种族都是竞争条件,但他们都可能会导致并发程序以不可预知的方式失败。
由Joshua布洛赫公司的Java并发实践 -从优秀图书采取