private static Callback callback;

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

private static Callback getCallback()
{
    callback = new Callback();
    return callback;
}

构造函数 Foo() 可能会从多个线程调用。我关心的是私有静态字段“callback”和静态方法“getCallback()”。

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

我的 猜测 是它不是线程安全的,因为关键字 静止的 始终附加到类而不是实例,因此这意味着 Foo 的静态字段“callback”可能会被构造另一个 Foo() 的其他线程覆盖。它是否正确?

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

编辑:我的目的是将“回调”保留在类中的某个位置,以便以后可以重用它。但这并不容易,因为 Foo 继承自一个类,该类具有强制传递“回调”的构造函数。

有帮助吗?

解决方案

是的,你是正确的。这是可能的Foo的两个实例使用相同CallBack情况下结束,当两个线程同时进入getCallback()方法之一,而另一个已经做到了这一点,但没有返回一个新的CallBack分配给静态字段。在这种情况下,最好的解决方法是不具有静态字段,因为它没有任何意义。可替换地,使getCallback()同步。

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

其他提示

这不是线程安全的。尝试这些替代选择:

选项1:这里所有实例共享相同的回调

private static final Callback callback = new Callback();

public Foo() {
    super(callback);
}

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

public Foo() {
    super(new Callback());
}

请注意,在这两种情况下,虽然构造函数是线程安全的,整个班级的线程安全取决于回调的实现。如果它有可变的状态,那么你就会有潜在的问题。如果回调是不可改变的,那么你有线程安全的。

回调将获得新的值每一次的Foo()被调用(甚至在同一个线程)。我不太清楚你的代码应该做的(如果你想只有一次(单身初始化静态变量),你应该检查,如果它仍然是空的getCallback() - 什么是actionCallback?)。用于使得线程安全的,使用同步。

我想你总结的那样完美自己,但没有更详细的关于你正在努力实现这将是棘手的提出建议,以解决您的问题是什么。

一个明显的问题是,不callback已经是静态的?或者,你能安全地使一个实例字段而不破坏你的类的功能?

我知道这个问题已经得到解答,但原因还没有详细说明。

如果两个线程调用 getCallback() 方法,它们可以执行如下几行:

  1. 线程 1 - 回调 = new Callback();
  2. 线程 2 - 回调 = new Callback();
  3. 线程1——返回actionCallback;
  4. 线程2——返回actionCallback;

在这种情况下,在 (2.) 处生成的回调将在 (3.) 和 (4.) 中返回

解决方案似乎是问为什么回调是静态定义的,如果它特定于实例而不是类。

我希望这有帮助。

你所试图做的是称为Singleton模式,如果你做一个搜索,你可以找出为什么它通常是一个好主意,如果你能避免这个模式,但是如果你需要它,你可以做到以下几点。

private static final Callback CALLBACK= new Callback();

或者如果你需要一个懒惰的单身,你可以做

public class Foo {
   class CallbackHolder {
       static final Callback CALLBACK= new Callback();
   }

   public static Callback getCallback() {
      return CallbackHolder.CALLBACK;
   }

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

两种实现都是线程安全。

你想每一个线程回调,每一个对象,或者一个真正的单身?

这是怎么做的不同的变体的一些草图 - 只是从我的头顶,不采取这些文生义:)

请注意,我假设回调有一个平凡的构造函数可能抛出异常,需要进行处理,如果它是一个平凡的构造可以简化所有这些很多。

一每线程:

  private static ThreadLocal<Callback> callback;

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

  private static Callback getCallback()
  {
      if ( callback.get() == null ) 
          callback.set(new Callback());
      return callback.get();
  }

针对所有线程单回调:

  private final static Callback callback;

  static {
      callback = new Callback(); 
  }

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

  private static Callback getCallback()
  {
      return callback;
  }

和,对于completness,每个对象一个回调:

  private Callback callback;

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

  private Callback getCallback()
  {
      callback = new Callback();
      return callback;
  }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top