在null对象上使用syncrhonized时获取NullPointerException

时间:2015-06-19 06:27:38

标签: java

我见过这个NullPointerException on synchronized statement

代码

synchronized(a){
    a = new A()
}

所以根据上面的回答我已经明白在null引用上不可能使用synchronized关键字。

所以我将代码更改为:

synchronized(a = new A()){}

但我不确定这是否与原始代码相同?

更新:

我想要实现的是锁定aa = new A()

的创建

3 个答案:

答案 0 :(得分:1)

Synchronized需要一个提供锁定机制的对象。它可以是任何对象(事实上,没有参数的同步将在 this 上同步),但Java API提供专用于此功能的类,例如ReentrantLock

在代码中,每次调用包含synchronized块的函数都会使用不同的对象进行锁定,有效地使同步无效。

编辑: 由于您使用实际尝试完成的内容更新了帖子,我可以为您提供更多帮助。

public class Creator {
    private A a;

    public void createA() {
        synchronized(this) {
            a = new A();
        }
    }
}

我不知道这是否适合您的设计,因为您提供的代码示例非常小,但您应该明白这一点。这里Creator类的实例用于同步A的创建。如果你在多个线程中共享它,每个线程调用createA(),你可以确定一个实例化进程将在另一个实例化进程开始之前完成。

答案 1 :(得分:0)

这两个代码段并不相同!

在第一个代码段中,您同步a引用的某个对象,然后更改不会更改同步对象的引用。

在第二个片段中,您首先分配一个新创建的对象以引用a,然后对其进行同步。因此同步对象将是新的。

通常,更改synchronized语句中使用的引用是一个非常糟糕的主意,无论它是在块内部(第一个代码)完成还是在synchronized语句(第二个代码)中直接执行。 最后决定!哦,也不能是null

答案 2 :(得分:0)

synchronized(a = new A()){}

  

所以它将会创建一个A类的新对象并使用它   作为Lock,所以简单来说每个线程都可以进入同步状态   随时阻止因为每个线程都有新的锁定而且会有   没有其他线程使用该对象作为锁,所以每个线程都可以   随时进入同步块,结果将是否定的   同步

例如

class TestClass {
    SomeClass someVariable;

    public void myMethod () {
        synchronized (someVariable) {
            ...
        }
    }

    public void myOtherMethod() {
        synchronized (someVariable) {
            ...
        }
    }
}
  

这里我们可以说那么这两个块将被执行保护   任何时候2个不同的线程,而someVariable没有被修改。   基本上,据说这两个块是同步的   变量some​​Variable。   但在您的情况下,总会有一个新对象,因此不会有同步