2012-08-09 30 views
2

我在一次採訪中被要求提出一個Singleton模式的設計/實現,我必須懶惰地加載類並且不使用同步關鍵字。我被嗆了,不能拿出任何東西。然後我開始閱讀java併發和concurrentHaspMap。請檢查下面的imlpementation,並確認您是否發現Double check Locking或此實現的任何其他問題。不使用同步關鍵字的單例實現的懶惰初始化

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; 
    } 
} 
+0

我認爲他們想聽到關於原子性的東西。 – gkuzmin 2012-08-09 07:54:02

+0

這個實現是不必要的複雜。有更簡單的方法來創建一個單身 - 請參閱下面Peter和我發佈的答案。 – munyengm 2012-08-09 08:35:48

回答

1

參見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; 
    } 
} 
+0

只是想問你,如果我使用「公共靜態最終Singleton INSTANCE =新的Singleton();」作爲Singleton類成員變量的一部分,這可能會有什麼不同? Inner類提供了什麼好處? – Metalhead 2012-08-09 09:08:16

+0

只有在調用getInstance()或訪問INSTANCE時纔會創建靜態內部類。在ClassLoader加載父類時,將創建一個靜態實例變量。有關如何初始化靜態實例變量的詳細信息,請參閱Java語言規範。 – munyengm 2012-08-09 11:25:32

3

它很簡單,如果你知道如何

enum Singleton { 
    INSTANCE; 
} 

INSTANCE是懶加載和線程安全的(和不使用任何形式的顯式鎖定)

+0

對不起,但我對枚舉還不太瞭解,我想你也可能是對的,但是你可以評論我分享的實現嗎?看到它有什麼漏洞嗎? – Metalhead 2012-08-09 08:02:55

+0

它可以創建多個SingletonMap,它比它需要的複雜得多。否則它可以工作。 – 2012-08-09 08:10:37