美文网首页
Volatile关键字

Volatile关键字

作者: evil_ice | 来源:发表于2017-01-08 22:00 被阅读17次
    • Java语言允许线程访问共享变量,为了确保一致和可靠地更新共享变量,一个线程应该通过一个获取一个锁来确保它独占使用变量.一般来说,可以通过互斥来实现.
      Java语言提供了第二个机制----volatile关键字, 他比锁更简单.被声明为volatile的变量,可以保证所有的线程可以一致的访问这个变量.
    • volatile提供了稍弱的同步机制,用来确保将变量的更新操作通知到其他线程.当变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将改变量上的操作与其他内存操作一起重排序.volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此读取volatile类型的变量时总会返回最新写入的值.
    • 总之,一句话, volatile保证共享变量值改变后,能被其他所有的线程看到

    一,不使用任何措施的示例

    public class VolatitleTest {
        
        public static void main(String[] args) {
            OneThread one = new OneThread();
            TwoThread two = new TwoThread();
            
            one.start();
            two.start();
        }
        
        static int i = 0, j = 0;
         static void one() { i++; j++; }
         static void two() {
             System.out.println("i=" + i + " j=" + j);
         }
        
         static class OneThread extends Thread{
             public void run(){
                 for(;;){
                     VolatitleTest.one();
                 }       
             }
         }
         
        static class TwoThread extends Thread{
             public void run(){
                 for(;;){
                     VolatitleTest.two();
                 }
             }
         }
    }
    

    将会出现方法two()打印的j的值大于i的值. 出现的原因就是当线程1对i和j进行自增后, i更新的值不能被线程2看到.

    二,使用synchronzied关键字

         static int i = 0, j = 0;
         static synchronized void one() { i++; j++; }
         static synchronized void two() {
             System.out.println("i=" + i + " j=" + j);
         }
    

    使用synchronzied关键字后,方法one()和方法two()不能并发的执行,从而保证了共享变量i和j在方法one()结束后都被更新.

    三,使用volatile关键字

        static volatitle int i = 0, j = 0;
         static void one() { i++; j++; }
         static void two() {
             System.out.println("i=" + i + " j=" + j);
         }
    
    • 当使用volatile修饰变量i,j的时候, 当i和j的值改变的时候, 线程立马的就可以看到改变后的值.
    • 但是当使用volatile之后,还会出现j比i大的情况,但是此时并不是因为i的值更改后不能被其他线程看见, 是因为多个线程同时操纵i和j造成的.
      与第二示例使用synchronized相比, synchronized的加锁机制可以确保可见性和原子性,而volatile仅仅可以确保可见性

    参考:
    <<java编发编程实战>>

    相关文章

      网友评论

          本文标题:Volatile关键字

          本文链接:https://www.haomeiwen.com/subject/txgqbttx.html