为什么在同步块中使用volatile

为什么在同步块中使用volatile

本文介绍了为什么在同步块中使用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;
    }

提前谢谢.

解决方案

在这种情况下,如果第一个检查位于同步块内,则仅使用同步本身就足够了(但不是这样,如果一个线程可能看不到另一个线程所做的更改,变量不易变).仅凭挥发就不够,因为您需要原子地执行多个操作.但是要当心!您在这里拥有的是所谓的双重检查锁定-一种常见的习惯用法,不幸的是运行不可靠.我认为自Java 1.6以来,这种情况已经发生了变化,但是这种代码仍然有风险.

编辑:当变量为volatile时,此代码自JDK 5起就可以正常工作(而不是我之前写的6),但在JDK 1.4或更早版本中将无法正常工作. >

I saw some examples in java where they do synchronization on a block of code to change some variable while that variable was declared volatile originally .. I saw that in an example of singleton class where they declared the unique instance as volatile and they sychronized the block that initializes that instance ... My question is why we declare it volatile while we synch on it, why we need to do both?? isn't one of them is sufficient for the other ??

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;
    }

thanks in advance.

解决方案

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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 18:24