繁体   English   中英

Java中的单例设计模式

[英]Singleton Design Pattern in Java

Singleton中的Double Lock检查通常写为:

public static Singleton getInstance()
{ 
    if (instance == null)
    {
        synchronized(Singleton.class) {  //1
            if (instance == null)          //2
                  instance = new Singleton();  //3
        }
    }
    return instance; //4
} 

在上面的代码中,假设有十个线程正在调用此方法,所有线程都超过了第一个if条件,然后一个线程进入了同步块并创建了实例。 即使创建了实例,剩余的9个线程也将一一出现,它们需要等待并依次通过同步块。 我希望任何线程一旦创建Singleton实例,其他所有线程都不应等待。 告诉我是否有解决方案?

如果您坚持使用惰性实例化,我认为没有解决方案。 您可以在声明instance变量时创建单例对象:

class Singleton {
    private static final instance = new Singleton();

    private Singleton() {} // prevent outside construction

    public static Singleton getInstance() {
        return instance; // no synchronization needed
    }
}

感谢eSniff的评论(以及yair的评论使我对eSniff的评论正确),这是Wikipedia中发布的线程安全和惰性方法:

class Singleton {
    private static class Holder {
        static final instance = new Singleton();
    }

    private Singleton() {} // prevent outside construction

    public static Singleton getInstance() {
        return Holder.instance; // no synchronization needed
    }
}

您是否测试了性能并得出了确实需要延迟初始化的明确结论? 如果是这样,请使用holder模式

public static class Singleton {
    private static class InstanceHolder {
        public static Singleton instance = new Singleton();
    }

    private Singleton(){}

    public static Singleton getInstance() { 
        return InstanceHolder.instance;
    }
}

但是 ,如果您没有经过良好的性能测试,那么最简单的方法就是在实例声明中初始化单例( 渴望初始化 ),如下所示:

public static class Singleton {
    public static Singleton instance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance() { 
        return instance;
    }
}

这两种模式允许依靠类加载过程来确保使用Singleton视图的任何线程都具有一致的实例。 这样,您可以获得两个好处:代码更具可读性,并且运行速度更快。

顺便说一句,除非您将Singleton.instance声明为volatile否则Double-Check-Idiom并不是线程安全的。

如果您的10个线程同时使用此Singleton对象,则它将在操作中同时修改该对象的每个线程产生问题。 为了避免这种情况,我们使用了synced关键字,因此一次只有一个线程可以访问Singleton类的对象。 如果您希望所有线程都可以同时访问该对象,请删除sync关键字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM