并发编程(二)---关键字volatile

volatile内存语义

valatite是java虚拟机提供的轻量级的同步机制。valatile有关键字有如下两个作用:

  1. 保证被volatile修饰的共享变量对所有线程总数可见的,也就是当一个线程修改了被volatile修饰的值,另外一个线程能立即得知。
  2. 禁止指令重排

volatile的可见性

关于volatile的可见性作用,我们必须意识到被volatile修饰的变量对所有线程总数立即可见的,对volatile变量所有写操作总是能立即反应到其他线程中
看以下代码,a线程修改flag值后会立马通知到线程b,去掉volatile后代码会出现死循环。

public class test {
    volatile boolean flag=false;
   public  void  save(){
       this.flag=true;
   }
   public  void  load(){
       while (!flag){

       }
       System.out.println(flag);
   }
   public static void main(String[] args) throws InterruptedException {
       test test=new test();
       Thread threada=new Thread(()->{
           test.save();
       });
       Thread threadb=new Thread(()->{
           test.load();
       });
       threadb.start();
       Thread.sleep(1000);
       threada.start();
   }
}

volatile无法保证其原子性

public class VolatileVisibility {
    public static volatile int i =0;
    public static void increase(){
        i++;
    }
}

在并发环境下,i变量的任何改变都回立马反应到其它线程中,但是多条线程同时调用increase()方法的话,就会出现线程安全问题,毕竟i++操作不具有原子性,该操作是先取值,然后再写回一个新值,相当于原来的值加一,分两步完成,如果第二个线程在第一个线程读取旧值和写回新值期间读取i的域值,那么第二个线程就会和第一个线程一起看到同个值,并执行相同值加1的操作,这就造成了线程安全失败。因此必须用synchronized方法修饰,以确保线程安全,需要注意的是一旦使用synchronized修饰方法后,由于synchronized本身也具备与volatile相同的特性,即可见性,因此在这样的情况下就完全可以省去volatile修饰变量。

volatile禁止重排优化

volatile关键字另一个作用就是禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。
以下是JMM针对编译器制定的volatile重排序规则表。
在这里插入图片描述

class VolatileBarrierExample {
       int a;
       volatile int v1 = 1;
       volatile int v2 = 2;
       void readAndWrite() {
           int i = v1;      // 第一个volatile读
           int j = v2;       // 第二个volatile读
           a = i + j;         // 普通写
           v1 = i + 1;       // 第一个volatile写
          v2 = j * 2;       // 第二个 volatile写
       }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值