Volatile 关键字与可见性

Volatile 关键字

在Java语言中,使用volatile关键字修饰的变量在多线程情况下会保证该变量对所有线程的可见性。所谓的可见性是指一个线程对某个使用volatile关键字修饰的变量修改的结果会立刻让其他线程也能知道。简单来说就是一个线程修改的结果,其他线程立刻就能知道。

使用volatile关键字修饰的变量有两种特性:

1.确保该变量对所有线程的可见性。

2.禁止指令重排序优化。具体意思如下:

  • 第一个操作为读操作时,第二个任何操作不可以重排序到第一个前面。
  • 第二个操作为写操作时,第一个任何操作不可以重排序到第二个后面。
  • 第一个操作为写操作时,第二个任何操作不允许进行重排序。

可见性

在各个线程的工作内存中,volatile变量也存在不一致的情况。因为volatile变量对所有线程并不是立即可见的,但是线程每次使用该变量之前必须先刷新(即从主内存中重新执行read、load),导致线程每次用到的都是最新的值,执行引擎看不到不一致的情况,因此可以认为不存在不一致性问题。

原子性

由JMM保证的原子性变量操作包括read、load、assign、use、store和write。尽管虚拟机未把lock和unlock操作直接开放给用户使用,但是却提供了更高层次的操作–synchronized关键字,因此在 synchronized 块之间的操作也具备原子性。

有序性

在本线程内观察,所有的操作都是有序的;如果在一个线程中观察另一个线程,所有的操作都是无序的。

Java语言提供了volatile和synchronized两个关键字来保证线程之间操作的有序性,volatile关键字本身包含了禁止指令重排序的语义,而synchronized则是由“一个变量在同一个时刻只允许一条线程对其进行lock操作”这条规则获得,这条规则决定了持有同一个锁的两个同步块只能串行进入。

你可能感兴趣的:(java)