【问题标题】:Singleton With Arguments带参数的单身人士
【发布时间】:2013-09-15 19:35:42
【问题描述】:

在其静态构造函数中接受一个参数的单例是个好主意吗?我会遇到并发问题吗?

public class DataHelper {
    private static DataHelper singleton = null;
    private Listener<Object> listener;

    public static DataHelper getInstance(Listener<Object> listener) {
        if(singleton == null) {
            singleton = new DataHelper();
        }
        singleton.listener = listener;

        return singleton;
    }
}

【问题讨论】:

  • 即使没有参数也会有并发问题。
  • 您应该在构造函数上使用Lock。此外,为多个侦听器设计(为什么不呢?)并将ArrayList&lt;MyListnerInterface&gt; 与addListener 和removeListener 方法一起使用。
  • 单例(设计模式)本身并不是一个好的选择。使用 Dagger 或 RoboGuice 注入单例。
  • 我很高兴听到这个消息! =) 我是否必须在数据访问期间手动管理同步?
  • 我猜你可能想使用Flyweight pattern而不是单例。

标签: java android design-patterns singleton


【解决方案1】:

虽然它可能还不错(取决于您的需求),但这绝对不是一个好主意。既然在调用 getInstance() 时已经有了一个“监听器”对象,为什么不将它作为参数传递给单例的成员函数呢?您的函数中有两个竞争条件,一个是在创建单例时,另一个是在设置“侦听器”成员变量时。第二个可以通过根本不传递参数来避免。即使在单线程环境中,你也有问题

void foo() {
  DataHelper dh = DataHelper.getInstance(listener1);
  bar();
  // dh.listener no longer points to listener1
}

void bar() {
  DataHelper dh = DataHelper.getInstance(listener2);
}

如果有帮助,您还应该阅读有关依赖注入的内容。

【讨论】:

    【解决方案2】:

    向 Singleton 添加参数不会引入竞争条件(除非您传递对共享对象的引用)。然而,这个实现已经有一个竞争条件。什么可以防止两个线程同时调用该方法?单例不受保护。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多