帮助查看以下代码,它是否安全?

His*_*His 3 java multithreading static-methods

private static Callback callback;

public Foo()
{
    super(getCallback());
}

private static Callback getCallback()
{
    callback = new Callback();
    return callback;
}
Run Code Online (Sandbox Code Playgroud)

可以从多个线程调用构造函数Foo().我关注的是私有静态字段'callback'和静态方法'getCallback()'.

可以看出,每次调用'getCallback()'时,它都会为静态字段'callback'分配一个新值.

我的猜测是它不是线程安全的,因为关键字static总是附加到类而不是实例,这意味着,Foo的静态字段'回调'可能被构造另一个Foo()的其他线程覆盖.它是否正确?

如果我错了,请纠正我.谢谢!

编辑:我的目的是在课堂的某个地方保留'回调',以便我以后可以重复使用它.但这并不容易,因为Foo从一个具有构造函数强制'回调'的类扩展而来.

Mic*_*rdt 6

是的,你是对的.当两个线程同时进入方法时,两个实例可能会以Foo相同的CallBack实例结束,一个实例为静态字段getCallback()分配一个新实例,而另一个实例CallBack已经完成此操作但尚未返回.在这种情况下,最好的解决方法是不要使用静态字段,因为它没有用处.或者,使getCallback()同步.

但是请注意,这是不是真的,只有static在代码中的关键字结果不是线程安全的.


Ste*_*eod 5

它不是线程安全的.尝试这些替代品:

选项1:此处所有实例共享相同的回调

private static final Callback callback = new Callback();

public Foo() {
    super(callback);
}
Run Code Online (Sandbox Code Playgroud)

选项2:这里每个实例都有自己的回调

public Foo() {
    super(new Callback());
}
Run Code Online (Sandbox Code Playgroud)

请注意,在这两种情况下,虽然构造函数是线程安全的,但整个类的线程安全性取决于Callback的实现.如果它具有可变状态,那么你将有潜在的问题.如果Callback是不可变的,那么你就有线程安全性.