Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该同时使用lock和volatile吗?_Java_Locking_Volatile - Fatal编程技术网

Java 我应该同时使用lock和volatile吗?

Java 我应该同时使用lock和volatile吗?,java,locking,volatile,Java,Locking,Volatile,我对volatile的理解是,它确保始终从内存中读取值,因此,就我所见,在以下示例中,myObject变量需要是volatile的,以避免引发NullPointerException: private final Object lock = new Object(); private MyObject myObject = null; //... synchronized (lock) { if (myObject == null) { myObject = new

我对volatile的理解是,它确保始终从内存中读取值,因此,就我所见,在以下示例中,
myObject
变量需要是volatile的,以避免引发
NullPointerException

private final Object lock = new Object();
private MyObject myObject = null;

//...

synchronized (lock) {
    if (myObject == null) {
        myObject = new MyObject();
    }

    myObject.blah();

    // some other stuff that I want synchronized
}
myObject
仅在同步块中接触过<代码>锁定仅用于同步该块

对吗


所以稍微换一句话,我的问题是……想象一下,两个线程正在访问该代码。第一个线程锁定并设置myObject,调用同步块中的
.blah()
和任何其他代码,并退出同步块。这允许线程2进入同步块。如果不将
myObject
设置为volatile,是否仍有可能将
myObject==null
计算为
true

我认为这里不需要volatile,因为进入同步块的每个线程都在检查myObject引用,所以当第一个线程进入块时,myObject应该实例化,通过检查myObject是否为not null来保护其他线程。对我来说看起来不错


编辑:我希望只有这一个块需要使用myObect引用,并且不要在synchoronize块之前或之后更改此引用。

我认为这里不需要volatile,因为进入同步块的每个线程都在检查myObject引用,所以,当第一个线程进入块时,应该实例化myObject,其他线程通过检查is myObject not null来保护。对我来说看起来不错


编辑:我希望只有这一个块您想要使用myObect引用,并且您不要在同步块之前或之后更改此引用。

同步的
块将确保其他线程可以看到对内存的更新。无需使
myObject
易失性

发件人:

当一个线程释放一个内在锁时,在 在该行动和任何后续行动之间建立关系 获取相同的锁


synchronized
块将确保其他线程可以看到对内存的更新。无需使
myObject
易失性

发件人:

当一个线程释放一个内在锁时,在 在该行动和任何后续行动之间建立关系 获取相同的锁



myObject
是否易变?另外,类的所有实例的
对象锁是否都是常量?@LuiggiMendoza-请参见编辑。是否有其他代码可以将
myObject
设置为
null
?@SotiriosDelimanolis-不,想象一下这个代码是自包含的。我想可能有这样的机会,我在使用
同步的
块时没有这么愉快的经历,发生意外结果且同步不起作用,尤其是在流程开始时。更好地使用ReentrantLock
。至于
volatile
,在这种情况下,它与同步无关,因此不需要。myObject
是volatile吗?另外,类的所有实例的
对象锁是否都是常量?@LuiggiMendoza-请参见编辑。是否有其他代码可以将
myObject
设置为
null
?@SotiriosDelimanolis-不,想象一下这个代码是自包含的。我想可能有这样的机会,我在使用
同步的
块时没有这么愉快的经历,发生意外结果且同步不起作用,尤其是在流程开始时。更好地使用ReentrantLock
。至于
volatile
,在这种情况下,它与同步无关,因此不需要。但该值是否有可能存在于缓存中的某个位置,从而导致NPE?没有。没有这种可能性。在粘贴的代码中,每个线程(但一次只有一个)都会检查myObject值,然后运行blah方法,这样其他线程都会等待。但您不能在设置myObject=null的地方实现第二个块,因为这样会发生如您所说的事情。如果要将null设置为myObject,则需要在一个块中执行。但该值是否有可能位于缓存中的某个位置,从而导致NPE?没有。不存在这种可能性。在粘贴的代码中,每个线程(但当时只有一个)都将检查myObject值,然后运行blah方法,因此其他线程都将等待。但您不能在设置myObject=null的地方实现第二个块,因为这样会发生如您所说的事情。如果你想将null设置为myObject,你需要在一个块中完成。我一直在做一些研究,我想知道为什么我认为你需要volatile关键字。我相信这与DCL有关,这是:。现在我说的对吗?因为我的同步循环外部没有null检查,我不需要检查?我一直在做一些研究,因为我想知道为什么我认为你需要volatile关键字。我相信这与DCL有关,这是:。现在我说的对吗,因为我的同步循环外部没有null检查,所以我不需要检查?