volatile修饰符使用场景

2019-04-15  本文已影响0人  TryCatch菌

volatile修饰符使用场景

在多线程并发编程中,经常使用的是线程锁,例如 synchronized,其实在某些特定场景下,可以使用volatile这个轻量级的 “synchronized” 来实现。volatile 它在多线程编程中能保共享变量的可见性。可见性的意思按照并发编程的艺术这边书上描述的就是:“当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值”。

书面说法的volatile使用场景:

这里就不画什么内存图,做什么底层原理描述了,书上的描述绝对比我自己的口水话清楚,这里算是看并发编程的艺术这本书的时候,因为volatile这个修饰符用的场景比较少,做个记录,下面用代码跑一下。

使用场景

synchronized不通,在多线程的操作下,不保证变量的原子性,也就是说在多线程下只保证能取出当前最新值,而不保证在多线程同时操作变量的那一瞬间是唯一的,原子性的操作。

package com.wzh.demo.concurrentProgrammingArt.lock;

/**
 * @desc: volatile修饰符测试
 * @author: wzh
 * @date: 2019年4月14日
 */
public class VolatileTest implements Runnable{
    private  boolean running = true;
      
    public boolean isRunning() {
        return running;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    @Override
    public void run() {
        while(running){
            
        }
        System.out.println("子线程"+Thread.currentThread().getName()+"停止");
        
    }
    
    @SuppressWarnings("static-access")
    public static void main(String[] args) throws InterruptedException {
          VolatileTest task = new VolatileTest();
        //启动子线程
        new Thread(task).start();
        Thread.currentThread().sleep(1000);
        task.setRunning(false);
        System.out.println("主线程停止");
      }

    
}

这段代码运行会发现子线程不会停止,因为没有错操作去内存中都数据,子线程中的running一直是true

代码修改一下,running 加volatile修饰符

package com.wzh.demo.concurrentProgrammingArt.lock;

/**
 * @desc: volatile修饰符测试
 * @author: wzh
 * @date: 2019年4月14日
 */
public class VolatileTest implements Runnable{
    private volatile boolean running = true;
      
    public boolean isRunning() {
        return running;
    }

    public void setRunning(boolean running) {
        this.running = running;
    }

    @Override
    public void run() {
        while(running){
        }
        System.out.println("子线程"+Thread.currentThread().getName()+"停止");
        
    }
    
    @SuppressWarnings("static-access")
    public static void main(String[] args) throws InterruptedException {
          VolatileTest task = new VolatileTest();
        //启动子线程
        new Thread(task).start();
        Thread.currentThread().sleep(1000);
        task.setRunning(false);
        System.out.println("主线程停止");
      }

    
}

运行结果

主线程停止
子线程Thread-0停止

总结

上一篇 下一篇

猜你喜欢

热点阅读