并发编程八:volatile关键字

    xiaoxiao2026-01-08  4

    并发编程之volatile关键字

    介绍

    使用volatile关键字修饰的变量会对所有线程具有可见性。简单理解就是每当线程要访问该变量时,首先会对该变量值同步到主存,然后再访问该变量值。 如果明白java内存模型就能够更好的理解上面说的意思了。 volatile常被误用当作原子操作,其实volatile最常用的是修饰标识符。
    使用volatile关键字必须具备以下两个条件 1、运算结果不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值 2、变量不需要和其它的状态变量共同参与不变约束
    由于volatile变量只能保证可见性,并不能保证原子性操作,在一些场景下我们还是需要通过同步代码块或加锁来保证原子性。

    volatile关键字使用

    误用场景

    Counter Code public class Counter { // 声明可见性变量 private static volatile int count = 0;

    // 自增方法 public int incr() { return (++count); } //setter 和 getter方法 }

    CounterThread Code

    public class CounterThread implements Runnable { private Counter counter; public CounterThread(Counter counter) { this.counter = counter; } @Override public void run() { for (int i = 0; i < 1000; i++) { counter.incr(); } } }

    MainApp

    public class MainApp { public static void main(String[] args) { Counter counter = new Counter(); CounterThread counterThread = new CounterThread(counter); new Thread(counterThread).start(); new Thread(counterThread).start(); new Thread(counterThread).start(); new Thread(counterThread).start(); try { Thread.sleep(100); System.out.println(counter.getCount()); } catch (InterruptedException e) { e.printStackTrace(); } } } //每次计算出的结果都是小于等于4000,不确定的数。这就证明了volatile并不能保证变量操作是原子性的

    解决办法 1、使用同步代码块将incr变为同步方法 2、使用锁机制,同步incr内部操作count的代码 3、使用AtomicInteger类型声明变量,然后使用incrementAndGet方法

    // 自增方法 public int incr() { synchronized (this)//同步代码块 { return (++count); } }

    正确的使用场景

    1、作状态标识符

    public class Resource { // 标识符(true表示有资源,false表示没有资源) private volatile boolean flag = false; private String name; }

    2、double check(双重校验)

    //即线程安全的单例设计模式 class Singleton{ private volatile static Singleton instance = null; private Singleton() { } public static Singleton getInstance() { if(instance==null) { synchronized (Singleton.class) { if(instance==null) instance = new Singleton(); } } return instance; } }

    总结

    volatile关键字修饰的变量只是表明该变量对线程可见,并不能保证变量操作的元仔性。学习java内存模型深入理解。

    参考

    1、深入理解java虚拟机 2、http://www.ibm.com/developerworks/cn/java/j-jtp06197.html

    转载请注明原文地址: https://ju.6miu.com/read-1305803.html
    最新回复(0)