6

Concurrency in Practice 中,它说您可以使用 volatile 变量,如果

对变量的写入不依赖于其当前值。

所以,如果你有一个共享的、可变的变量a,并且所有线程对它做的都是 go a++(他们没有得到值,他们只是++)。

volatile然后根据报价,即使a++不是原子的,您也应该能够做到,对吗?

4

4 回答 4

8

不,++volatile变量上使用不是线程安全的,因为

a++

相当于:

int temp = a;
temp = temp + 1;
a = temp;

所以写回a可能发生另一个线程修改后a,因为你的线程读取它,所以a++,即使a是易失的,也不是线程安全的。

您可以使用AtomicInteger,它实现了线程安全的原子增量。

于 2012-11-04T16:56:30.997 回答
6

a++ 读取 a 的值,因为它等价于

  • 读一个
  • 增加读取值
  • 将新值分配给 a

所以不,在这种情况下你不能安全地使用 volatile 变量。

于 2012-11-04T16:57:03.210 回答
3

- 易失性做以下事情:

  • 标记的字段volatile将立即将其值写入内存,并在退休期间从内存中读取其

  • 防止在 Thread 中缓存

例如:

a++ 可以解释如下:

-读取名为 a 的内存位置的值。

-增加值。

-将新增加的值写入名为 a 的内存位置。

现在上面的整个过程都是not 线程安全的,++ Java中的(增量运算符)不是原子语句。

-最好使用synchronized关键字,或者如果您不喜欢使用它,请使用AtomicIntegerClass。

于 2012-11-04T17:48:52.397 回答
1

a++ 不是原子的,它等价于

  • 检索一个
  • 加 1
  • 将结果存储回

因此,如果另一个线程妨碍您,您仍然可以“错过更新” - volatile 并非旨在防止这种情况,这就是“同步块”和“锁”的用途。

a 易失性的事实仅影响其在线程中的可见性,因为 a 不存储在本地缓存中,因此不同的线程(在不同的内核或处理器上运行)可以立即“看到”它的新值。

于 2012-11-04T17:43:01.413 回答