一步一步学多线程-volatile关键字

并发编程的两个关键问题

1、  线程间通信

  常见的两种交换信息的机制

  A、 共享内存:读写内存中的公共状态来隐式通信

  B、 消息传递:无公共状态,通过发送消息来显示进行通信。              

2、线程间同步

  用以控制不同线程间操作发生的相对顺序的机制

  A、 共享内存下的通信机制,这里必须进行显示同步

  B、 消息传递的通信机制下,消息的发送顺序隐式进行了同步

 

  Java采用共享内存模型,线程间的通信过程对外完全透明。

volatile解决实例变量可见性

         在当前Java内存模型下,线程可以把变量保存到本地内存中,而不是直接在主内存中读写,这就可能造成一个线程在主内存中修改了变量的值,而另一个线程还继续使用它本地内存的变量值,造成数据不一致。这个问题其实就是私有堆栈中的值和公共堆栈中的值不同步造成的。

            

  解决这个问题就可以使用volatile关键字,volatile保证指令赋值完后的变量立即同步回主内存中,声明并通知其他线程当前赋值的变量已经失效,其他线程在下次使用时会放弃工作内存中的变量,使用主内存中的变量。

              

  所以,volatile关键字增加了实例变量在多个线程之间的可见性。但是volatile关键字并不支持原子性。volatile的关注点在于工作内存刷新回主内存。

比较volatile和synchronized

性能

         关键字volatile是线程同步的轻量级实现,所以volatile性能要比synchoronized要好。但随着JDK新版本的发布,synchronized关键字在执行效率上得到很大提升,在开发中使用synchronized关键字的比率还是比较大的。 多线程访问volatile不会发生阻塞,而synchronized会出现阻塞

原子性

         volatile能保证数据的可见性,但是不能保证原子性,而synchronized既能保证原子性也能保证可见性。

范围

         volatile只能修饰变量,而synchronized可以修饰方法以及代码块。     

有序性实现

  volatile关键字本身就包含了禁止指令重排的语义,而synchronized则是由“一个变量在同一时刻只允许一条线程对其进行Lock操作”这条规则获得的,这条规则决定了持有同一个锁的两个同步代码块只能串行的进入。

 

posted @ 2017-08-21 10:01  一步一步学  阅读(116)  评论(0编辑  收藏  举报