为什么在同步块中使用volatile? [英] why using volatile with synchronized block?

查看:99
本文介绍了为什么在同步块中使用volatile?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java中看到了一些示例,它们在代码块上进行同步以更改某些变量,而该变量最初被声明为volatile.同步了初始化该实例的块...我的问题是,为什么我们在对其进行同步时将其声明为volatile,为什么我们需要同时做这两个?不是其中一个足以满足另一个需求吗?

public class someClass {
volatile static uniqueInstance = null;

public static someClass getInstance() {
        if(uniqueInstance == null) {
            synchronized(someClass.class) {
                if(uniqueInstance == null) {
                    uniqueInstance = new someClass();
                }
            }
        }
        return uniqueInstance;
    }

提前谢谢.

解决方案

在这种情况下,如果第一个检查位于同步块内,则仅使用同步本身就足够了(但不是这样,如果一个线程可能看不到另一个线程所做的更改,变量不易变).仅凭挥发就不够,因为您需要原子地执行多个操作.但是要当心!您在这里拥有的是所谓的双重检查锁定-一种常见的习惯用法,不幸的是 解决方案

Synchronization by itself would be enough in this case if the first check was within synchronized block (but it's not and one thread might not see changes performed by another if the variable were not volatile). Volatile alone would not be enough because you need to perform more than one operation atomically. But beware! What you have here is so-called double-checked locking - a common idiom, which unfortunately does not work reliably. I think this has changed since Java 1.6, but still this kind of code may be risky.

EDIT: when the variable is volatile, this code works correctly since JDK 5 (not 6 as I wrote earlier), but it will not work as expected under JDK 1.4 or earlier.

这篇关于为什么在同步块中使用volatile?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆