【问题标题】:What is the difference between sequential consistency and atomicity?顺序一致性和原子性有什么区别?
【发布时间】:2013-03-18 06:33:04
【问题描述】:

我读到 java volatile 是顺序一致的,但不是原子的。 对于原子性,java 提供了不同的库。

有人可以用简单的英语解释两者之间的区别吗?

(我相信问题范围包括 C/C++,因此添加这些语言标签以获得更多的受众。)

【问题讨论】:

  • 我不认为volatile 在 C/C++ 中提供与在 Java 中相同的保证。特别是,我不认为它在 C 中提供了您所谓的顺序一致性(即内存围栏适用于其他变量)-TBC。
  • @assylias 我并不是说 volatile 在 C/C++ 中具有相同的含义。我确信它不会。我指的是 c/C++ 和 Java 之间常见的“顺序一致性和原子性”的概念。在 C/C++ 中,volatile 关键字停止了变量使用的优化,并且不用于维护在使用 volatile 变量的操作之前指定的操作之间的顺序一致性。

标签: java c++ atomic volatile


【解决方案1】:

想象一个类中的这两个变量:

int i = 0;
volatile int v = 0;

还有这两种方法

void write() {
    i = 5;
    v = 2;
}

void read() {
    if (v == 2) { System.out.println(i); }
}

volatile 语义保证read 要么打印5,要么什么也不打印(当然,假设没有其他方法正在修改字段)。如果v 不是易失性的,read 还不如打印 0,因为 i = 5v = 2 可能已经重新排序。我想这就是你所说的顺序一致性的意思,它有更广泛的含义。

另一方面,volatile 不保证原子性。所以如果两个线程同时调用这个方法(v同volatile int):

void increment() {
    v++;
}

你无法保证 v 会增加 2。这是因为 v++ 实际上是三个语句:

load v;
increment v;
store v;

由于线程交错,v 只能增加一次(两个线程将加载相同的值)。

【讨论】:

  • 如果您可以添加一个示例来演示原子和顺序的东西,那将是完整的答案。我们可以在不使用互斥锁的情况下做到这一点吗?
  • 现在不能更新但是可以,所以 cslled 无锁算法使用 CAS 操作来提供原子性。它被 java 中的所有 AtomicXXX 类使用。
【解决方案2】:

假设你有这两个变量:

public int a = 0;
public volatile int b = 0;

假设一个线程可以

a = 1;
b = 2;

如果另一个线程读取这些值并看到 b == 2,那么它肯定也会看到 a == 1。

但是读取线程可以看到a == 1b == 0,因为这两个写入不是原子操作的一部分,所以读取线程可能会在第一个线程分配值之前看到对a所做的更改到b

要使这两个写入原子化,您需要同步对这两个变量的访问:

synchronized (lock) {
    a = 1;
    b = 2;
}

...

synchronized (lock) {
    System.out.println("a = " + a + "; b = " + b);
}

在这种情况下,读取线程将看到a == 0b == 0,或a == 1b == 2,但不会看到中间状态。

【讨论】:

  • +1,但您并不是真的在说“这是顺序一致性”和“这是原子性”。
  • 是的,我认为这很明显。但无论如何 assylias 的答案比我的更清楚更好。
猜你喜欢
  • 2018-03-17
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 2010-09-09
  • 2012-04-02
  • 2012-02-10
  • 2011-06-20
  • 2011-11-14
相关资源
最近更新 更多