我见过这个NullPointerException on synchronized statement。
代码:
synchronized(a){
a = new A()
}
所以根据上面的回答
所以我将代码更改为:
synchronized(a = new A()){}
但我不确定这是否与原始代码相同?
更新:
我想要实现的是锁定a
(a = new A()
)
答案 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没有被修改。 基本上,据说这两个块是同步的 变量someVariable。 但在您的情况下,总会有一个新对象,因此不会有同步