Java 带参数的单例

Java 带参数的单例,java,android,design-patterns,singleton,Java,Android,Design Patterns,Singleton,让一个接受静态构造函数中参数的单例是一个好主意吗?我可以有并发问题吗 public class DataHelper { private static DataHelper singleton = null; private Listener<Object> listener; public static DataHelper getInstance(Listener<Object> listener) { if(singleto

让一个接受静态构造函数中参数的单例是一个好主意吗?我可以有并发问题吗

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;
    }
}
公共类DataHelper{
私有静态DataHelper singleton=null;
私人倾听者;
公共静态DataHelper getInstance(侦听器侦听器){
if(singleton==null){
singleton=newdatahelper();
}
singleton.listener=listener;
返回单身;
}
}

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

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

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

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

void bar() {
  DataHelper dh = DataHelper.getInstance(listener2);
}
如果有帮助的话,你也应该阅读有关依赖注入的内容。

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

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

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

如果有帮助,您还应该阅读依赖项注入。

即使没有参数,您也会遇到并发问题。您应该在构造函数上使用
锁。另外,设计多个侦听器(为什么不?),并将
ArrayList
addListener
removellistener
方法一起使用。单例(设计模式)本身不是一个好的选择。使用Dagger或RoboGuice注入单身汉。我很高兴听到这个消息!=)我是否必须在数据访问期间手动管理同步?我想您可能需要使用
Flyweight模式
,而不是单例模式。即使没有参数,也会出现并发问题。您应该在构造函数上使用
。另外,设计多个侦听器(为什么不?),并将
ArrayList
addListener
removellistener
方法一起使用。单例(设计模式)本身不是一个好的选择。使用Dagger或RoboGuice注入单身汉。我很高兴听到这个消息!=)我是否必须在数据访问期间手动管理同步?我想在您的情况下,您可能希望使用
Flyweight模式
,而不是单例模式。