6.22Java多线程volitale

6.22Java多线程volitale

volitale说明

作用:

保证线程间变量的可见性(注意:不是线程之间的变量可见)

线程A对变量X进行修改后,在线程A后面执行的其他线程能看到变量X的变动。

需要符合以下两个规则:

  • 线程对变量进行修改之后要立刻写回到主内存--->防止主内存与工作内存中不一致的情况

    • 加了volitale修饰,对变量的修改就会立刻写到主内存当中

    • 同时通知另一个线程拿到最新的

  • 线程对变量读取的时候要从主内存中读,而不是从缓存中读

线程工作模式图:

特点:

  • 各线程的工作内存间彼此独立、互不可见。

  • 在线程启动的时候,虚拟机为每个内存分配一块工作内存。

    • 包含了线程内部定义的局部变量

    • 线程所需要使用的共享变量(非线程内构造的对象)的副本

volatile的缺陷:--->只保证了同步的数据可见

volatile不能保证原子性

什么是原子性?

以代码a++举例,在汇编层面会分成三步

  1. 拿到a

  2. a+1计算结果

  3. 存储计算的结果到a中

这完整的三步是一个整体、一个变量。--->volatile不能保证这三个作为一个整体发生变化

volatile实例demo
package thread.rearrangement;

/**
* volatile用于保证数据的同步
* 可见性
* 粒度很小,只保证数据的同步
* 不保证原子性,可以避免指令重排!!!
* @since JDk 1.8
* @date 2021/6/22
* @author Lucifer
*/
public class VolatileTestNo1 {

   /*加一个类变量*/
   private volatile static int num = 0;

   public static void main(String[] args) {

       /*使用lambda表达式多线程操作变量*/
       new Thread(() -> {
           /*写一个死循环*/
           while (num==0){
               //这里不要编写代码--->目的是让cpu繁忙
          }
      }).start();

       /*一秒后改变值为1*/
       try {
           Thread.sleep(1000);
      }catch (InterruptedException e){
           System.out.println(e.getMessage());
           e.printStackTrace();
      }

       /*改变变量的值*/
       num = 1;

  }
   /*
   如果不加volatile那么线程不会停止
   加了volatile以后一秒后num已经发生改变,虽然不会回显(因为事务没有回写到主存)但是线程一样会停止
   保证数据的可见性,保证数据的重排
   不保证赋值操作的原子性
    */
}

 

posted @ 2021-06-23 10:13  俊king  阅读(66)  评论(0编辑  收藏  举报