Java中的volatile int是线程安全的吗?

Java中的volatile int是线程安全的吗? 也就是说,它可以安全地读取和写入,而不locking?

是的,你可以从中读取并安全地写入 – 但是你不能做任何事情,比如安全地增加它,因为这是一个读/修改/写周期。 还有一个问题是它如何与访问其他variables进行交互。

volatile的确切性质是坦率的混淆( 更多细节参见JLS的内存模型部分 ) – 我个人通常使用AtomicInteger作为一种更简单的方法来确保正确。

就像在没有locking的情况下能够安全地读取和写入一样?

是的,读取总是会导致最后一次写入的值(读取和写入都是primefaces操作)。

易失性读/写在执行过程中引入了所谓的“先发后发”关系。

从Java语言规范第17章:线程和锁

写一个易失字段(§8.3.1.4)发生在每个后续读取该字段之前。

换句话说,在处理volatilevariables时,您不必使用synchronized关键字来显式同步(引入一个before-before关系),以确保线程获取写入variables的最新值。

正如Jon Skeet指出的那样,volatilevariables的使用是有限的,你应该一般考虑使用java.util.concurrent包中的类来代替。

在Java中访问volatile int将是线程安全的。 当我说访问我的意思是单位操作,如volatile_var = 10或int temp = volatile_var(基本上写/读有恒定值)。 java中的volatile关键字确保了两件事情:

  1. 阅读时你总能得到主存的价值。 一般来说,为了优化的目的,JVM使用寄存器或者更一般的术语本地存储器来存储/访问variables。 所以在multithreading环境中,每个线程可能会看到不同的variables副本。 但是使其变为volatile可以确保写入variables被刷新到主内存中,并且从主内存中读取,从而确保该线程在variables的正确副本处查看。
  2. 访问易失性是自动同步的。 所以JVM在读/写variables时确保sorting。

然而Jon Skeet正确地提到,在非primefaces操作(volatile_var = volatile + 1)中,不同的线程可能会得到意想不到的结果。

如果一个volatile不依赖于任何其他的volatilevariables,它的线程安全的读取操作。 在写volatile的情况下不保证线程安全。

假设你有一个易变的variablesi,它的值依赖于另一个variablesvariablesj。 现在,线程1访问variablesj并递增,并将从CPUcaching中将其更新到主内存中。 如果线程2读取
Thread-1之前的variablesi实际上可以更新主内存中的j。 我的价值将按照j的旧价值,这将是不正确的。 它也被称为脏读。

不总是。

如果多个线程正在写入和读取variables,则线程不安全。 如果您有一个编写器线程和多个读取器线程,它是线程安全的。

如果您正在安全地寻找线程,请使用AtomicXXX类

一个支持单variables无锁线程安全编程的小型工具包。

本质上,这个包中的类将volatilevariables值,字段和数组元素的概念扩展为那些也提供了表单的primefaces条件更新操作的variables:

 boolean compareAndSet(expectedValue, updateValue); 

在下面的post中参考@teto答案:

易失性布尔与AtomicBoolean