Java 我应该同时使用lock和volatile吗?
我对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
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检查,所以我不需要检查?