你真的了解volatile吗?

格桑2021-12-03 15:23

  无论是在面试时,还是在实际开发中,高并发问题已经成为了现在的主旋律。

  并发问题的定位和重现是一件很棘手且难以解决的事情,为了尽可能的减少并发问题的产生,正确的编写并发程序显得尤其重要。

  解决并发问题,我们一般需要从原子性、可见性和有序性三方面入手,借助Java关键字及各种同步工具类来实现。

  原子性、可见性、有序性三特性:

  原子性:原子性就是说一个操作不能被打断,要么执行完要么不执行。

  可见性:可见性是指一个变量的修改对所有线程可见。即当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。

  有序性:为了提高程序的执行性能,编辑器和处理器都有可能会对程序中的指令进行重排序。

  其中,volatile作为Java中最轻量级的同步机制,可以被用来解决实例属性的可见性问题。

  volatile的两种特性,决定了它的作用

  volatile关键字是Java提供的最轻量级的同步机制,为字段的访问提供了一种免锁机制,使用它不会引起线程的切换及调度。

  一个变量被定义为volatile之后就具备了两种特性:

  可见性:简单地说就是volatile变量修改后,所有线程都能立即实时地看到它的最新值。

  有序性:指系统在进行代码优化时,不能把在volatile变量操作后面的语句放到其前面执行,也不能将volatile变量操作前面的语句放在其后执行。

  Java中的volatile关键字可以解决多线程可见性问题。那它是何时以及如何使用呢?

  下面我们一起来揭秘。

  初识Volatile:保证多线程下共享变量的可见性

  下面的两个例子演示了变量使用volatile和未使用volatile时,变量更新对多线程执行的影响。

你真的了解volatile吗?

  在VolatileDemo中,停止标识stop使用volatile关键字修饰,初始值为false。

  创建子线程thread1并启动,在子线程thread1任务中,当不满足停止条件时,线程会一直运行;当满足停止条件,终止任务。

  稍后,我们在主线程中设置停止标识为true。执行代码,结果如下图。

  我们可以看到在主线程设置stop=true后,子线程同时感知到stop的变化终止了任务。