同步语句的NullPointerException

时间:2011-06-22 00:17:44

标签: java

我尝试在下面的代码中同步一个对象:

public void myMethod() {
    synchronized (globalObj) {
        //Do something here
    }
}

代码在一个线程中执行。问题是,另一个线程可能将'globalObj'设置为null。然后,当'globalObj'被其他线程设置为null时,'synchronized(globalObj)'将抛出NullPointerxception。

同步对象的最佳做法是什么,因此不会抛出NullPointerException?

感谢。

4 个答案:

答案 0 :(得分:28)

您不应该在可能更改的引用上进行同步。如果允许另一个线程替换globalObj,这意味着您可以锁定旧的globalObj,而另一个线程可以使用完全不同的线程 - 锁定对您没有帮助。

您应该做的是为此目的单独Object

static final Object lockObj = new Object();

public void myMethod() {
  synchronized (lockObj) {
    // do something with globalObj here
  }
}

由于lockObj永远不会改变,因此您将始终使用相同的锁定 - 没有问题。

答案 1 :(得分:6)

您无法在null引用上进行同步。最佳实践是在final对象上进行同步(以确保它永远不会null),或者(更好地)在java.util.concurrent包中使用更高级别的并发抽象。

答案 2 :(得分:1)

确保在不能为null的对象上进行同步...

为什么要将globalObj设置为null?这应该是什么样的并发语义?这是偶然的吗?

如果锁定的必要性有时会消失(虽然看起来很奇怪),你可以添加一个空检查(当然,你需要同步其他东西以避免首先检查null的竞争条件,然后拥有它之后立即设为null。

请更详细地描述您的情景。

答案 3 :(得分:0)

创建一个私有对象类成员,该成员没有任何公共setter并锁定该成员。