【问题标题】:Lazy initialization of Singleton implementation without using Synchronized Key word不使用同步关键字的 Singleton 实现的延迟初始化
【发布时间】:2012-08-06 09:55:30
【问题描述】:

我在一次采访中被要求提出一个单例模式的设计/实现,我必须延迟加载类并且不使用同步关键字。我被噎住了,什么都想不出来。然后我开始阅读 java 并发和 concurrentHaspMap。请检查下面的实施,如果您发现任何与双重检查锁定有关的问题或与此实施有关的任何其他问题,请确认。

package Singleton;

import java.util.concurrent.ConcurrentHashMap;

public final class SingletonMap {

    static String key = "SingletonMap";
    static ConcurrentHashMap<String, SingletonMap> singletonMap = new ConcurrentHashMap<String, SingletonMap>();
    //private constructor
    private SingletonMap(){

    }
    static SingletonMap getInstance(){

        SingletonMap map = singletonMap.get(key);       
        if (map == null){
                //SingletonMap newValue=  new SingletonMap();
                map =   singletonMap.putIfAbsent(key,new SingletonMap());
                if(map == null){
                    map = singletonMap.get(key);    
                }
        }       
        return map;
    }
}

【问题讨论】:

  • 我认为他们想听听一些关于原子性的事情。
  • 这个实现是不必要的复杂。有更简单的方法来创建单例 - 请参阅下面 Peter 和我发布的答案。

标签: java concurrency singleton synchronized


【解决方案1】:

如果你知道怎么做就很简单

enum Singleton {
    INSTANCE;
}

INSTANCE 是延迟加载和线程安全的(并且不使用任何类型的显式锁定)

【讨论】:

  • 抱歉,我对枚举还不太了解,我认为您也可能是对的,但您能评论一下我分享的实现吗?看看有什么漏洞吗?
  • 它可以创建多个 SingletonMap,而且它比它需要的复杂得多。否则它可以工作。
【解决方案2】:

另见Bill Pugh's solution

public class Singleton {
    // Private constructor prevents instantiation from other classes
    private Singleton() {}

    /**
     * SingletonHolder is loaded on the first execution of
     * Singleton.getInstance() or the first access to
     * SingletonHolder.INSTANCE, not before.
     */
    private static class SingletonHolder {
        public static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

【讨论】:

  • 只是想问你,如果我使用“public static final Singleton INSTANCE = new Singleton();”作为 Singleton 类成员变量的一部分,这会有什么不同? Inner 类有什么好处?
  • 静态内部类仅在调用 getInstance() 或访问 INSTANCE 时创建。类加载器加载它的父类时,将创建一个静态实例变量。有关如何初始化静态实例变量的详细信息,请参阅 Java 语言规范。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-10
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
相关资源
最近更新 更多