Java多线程开发之volatile关键字

说明

  1. 多线程程序中,内存可见性问题,示例:
    如下代码会出现死循环问题:
class Thread1 implements Runnable {
    boolean flag = false;
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
        flag = true;
    }
}

public class Volatile {
    public static void main(String[] args) {
        Thread1 t1 = new Thread1();
        new Thread(t1).start();
        System.out.println(t1.flag);
        while (true) {
            if (t1.flag) {
                System.out.println("true--------");
                break;
            }
        }
    }
}

  出现死循环的原因是,每个线程都会开辟一块缓存内存用于操作共享数据,在堆共享数据操作完成后再返还给主存,在上面的程序中,t1线程执行中睡了1秒,这时主线程获取了执行权开始循环,并判断flag为假,而t1睡眠结束后修改了flag的值后,主线程获取的flag值是缓存中的flag值,所以一直循环,无法结束。
  解决方法:volatile关键字修饰线程共享数据volatile boolean flag = false;。被volatile修饰的变量,被操作时不会在缓存中,而是在主存中,这样就保证了线程间操作的可见性。

  1. volatile关键字的注意事项:
    (1)不具备synchronize的互斥性
    (2)不能保证变量的“原子性”
    (3)被修饰的变量不会被jvm优化重排序
发布了51 篇原创文章 · 获赞 20 · 访问量 1548

猜你喜欢

转载自blog.csdn.net/qq_39711439/article/details/101379961