java中的易失性和原子操作

Min*_*ang 3 java atomic volatile

我已阅读有关Java中原子操作的文章,但仍有一些疑问需要澄清:

int volatile num;
public void doSomething() {
  num = 10;  // write operation
  System.out.println(num)   // read
  num = 20;  // write
  System.out.println(num);  // read
}
Run Code Online (Sandbox Code Playgroud)

所以我在1方法上做了4次操作,它们是原子操作吗?如果多个线程同时调用doSomething()方法会发生什么?

mer*_*ike 6

如果没有线程将看到中间状态,则操作是原子的,即操作将完全完成,或者根本不完成.

读取int字段是原子操作,即一次读取所有32位.编写一个int字段也是原子的,该字段要么已完全写入,要么根本不写入.

但是,方法doSomething()不是原子的; 一个线程可能在执行该方法时将CPU输出到另一个线程,并且该线程可能会看到已经执行了一些但不是所有操作.

也就是说,如果线程T1和T2都执行doSomething(),则可能发生以下情况:

T1: num = 10;
T2: num = 10;
T1: System.out.println(num); // prints 10
T1: num = 20;
T1: System.out.println(num); // prints 20
T2: System.out.println(num); // prints 20
T2: num = 20;
T2: System.out.println(num); // prints 20
Run Code Online (Sandbox Code Playgroud)

如果doSomething()被同步,其原子性将得到保证,并且上述场景是不可能的.