简体   繁体   English

Java中的单例设计模式

[英]Singleton Design Pattern in Java

Double Lock check in Singleton is generally written as : 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
} 

In the code above, suppose ten threads are calling this method, all of them crossed the first if condition, then one thread enters into the synchronized block and creates the instances. 在上面的代码中,假设有十个线程正在调用此方法,所有线程都超过了第一个if条件,然后一个线程进入了同步块并创建了实例。 Remaining 9 thread would come one by one even if the instance is created they need to wait and come in sequence through the synchronized block. 即使创建了实例,剩余的9个线程也将一一出现,它们需要等待并依次通过同步块。 I want that as soon as any of the threads creates the Singleton instance all the other threads should not wait. 我希望任何线程一旦创建Singleton实例,其他所有线程都不应等待。 Tell me if there is some solution for this? 告诉我是否有解决方案?

I don't think there's a solution if you insist on using lazy instantiation. 如果您坚持使用惰性实例化,我认为没有解决方案。 You could just create your singleton object when you declare the instance variable: 您可以在声明instance变量时创建单例对象:

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

    private Singleton() {} // prevent outside construction

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

Thanks to the comment by eSniff (and the comment by yair to set me right about eSniff's comment), here's the method posted in Wikipedia for a thread-safe and lazy method: 感谢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
    }
}

Did you test performance and reached the definite conclusion that you really need lazy initialization? 您是否测试了性能并得出了确实需要延迟初始化的明确结论? If so, use the holder pattern : 如果是这样,请使用holder模式

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

    private Singleton(){}

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

But , if you're not after decent performance test, than the most simple thing to do is to initialize the singleton in its instance declaration ( eager initialization ), like so: 但是 ,如果您没有经过良好的性能测试,那么最简单的方法就是在实例声明中初始化单例( 渴望初始化 ),如下所示:

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

    private Singleton(){}

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

These two patterns, allow to rely on the class loading process to assure any thread that uses Singleton views a consistent instance. 这两种模式允许依靠类加载过程来确保使用Singleton视图的任何线程都具有一致的实例。 This way you achieve two benefits: code is more readable and runs faster. 这样,您可以获得两个好处:代码更具可读性,并且运行速度更快。

BTW, the Double-Check-Idiom isn't thread safe unless your Singleton.instance is declared volatile . 顺便说一句,除非您将Singleton.instance声明为volatile否则Double-Check-Idiom并不是线程安全的。

If your 10 thread are using this Singleton object at same time then it will create problem in manipulation every thread modified this object in same time. 如果您的10个线程同时使用此Singleton对象,则它将在操作中同时修改该对象的每个线程产生问题。 to avoid this we used synchronized keyword so at a time only one thread can access object of Singleton class. 为了避免这种情况,我们使用了synced关键字,因此一次只有一个线程可以访问Singleton类的对象。 if you want all thread can access this object at same time then remove synchronized keyword. 如果您希望所有线程都可以同时访问该对象,请删除sync关键字。

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

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