同步对象设置为空(synchronized object set to null)

2019-06-23 17:17发布

我有两个线程Thread1Thread2

//Within Thread1     
synchronized(obj1)  
{  
    obj1 = null;  
}  

//Within Thread2  
synchronized(obj1)  
{  
    do something  
}   

如果JVM首先执行线程1和套OBJ1为空,然后将线程2立即看到这种变化还是会花时间和JVM仍然可以运行线程2 synchronized块,因为OBJ1还没有空?

Answer 1:

这几乎肯定会打破同步的抽象-我不会相信, thread2将立即看到变化。 你不应该改变你同步的对象的引用,更不用说将它设置为null ,这将导致一个NullPointerException上的任何进一步尝试就可以同步。



Answer 2:

首先我要强调的是,修改用于同步的变量是一个非常糟糕的事情 ™。 obj1应该是final ,如果它被用作显示器从来没有被触及。

话虽这么说,回到你的问题:

如果JVM首先执行线程1,它同步于obj1 ,将它设置为null并且该线程退出。 第二个线程希望在同步obj1NullPointerException将被抛出。 因为修改obj1在同步块构成的,它保证了线程2将看到更新的值(因此: NullPointerException保证)。

如果线程1被获取的锁后中断obj1但清除引用之前,线程2将锁定obj1 ,等待线程1完成。 然后,它会顺利进入显示器,因为先前引用的对象obj1仍然存在。



Answer 3:

synchronized同步的对象,而不是参考。 通过设置obj1 (参考)为null,线程2不能以前由指向的对象上同步obj1 ,你会得到一个NullPointerException来代替。



Answer 4:

这种变化是立竿见影的。 当线程1“拥有”的锁,它可以随意改变OBJ1的价值。 线程2要等到线程1解除锁定。 它一定会看到OBJ1 == NULL



Answer 5:

快速的解决办法是使加工对象物1个元件的简单阵列,并且是指该阵列用于同步,例如,

对象[] OBJ1 = {NULL};

所述元件可以为空而不影响阵列的存在。 当然,这还打破了不使用同步对象本身的“规则”,但除非你的代码的其他地方复杂事项,预计今年速战速决应该工作。



文章来源: synchronized object set to null