2017年2月12日 星期日

單例模式

一個class只有一個實體


※餓漢式單例

public class Singleton {
    private static final Singleton SINGLETON = new Singleton();
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        return SINGLETON;
    }
}

※類別載入就創建物件,執行效率高,但浪費記憶體



※懶漢式單例

public class Singleton {
    private static Singleton singleton = null;
    
    private Singleton() {}
    
    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

※第一次請求實體才會創建物件,但必須要用synchronized

※如果不用 synchronized 有可能會有多個實體,因為Parallel程序可能會進入,如下:
public class Singleton {
    private static Singleton singleton = null;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (singleton == null) {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            singleton = new Singleton();
        }
        return singleton;
    }
}
    
    
    
public class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println(Singleton.getInstance());
    }
    
    public static void main(String... ss) {
        /*Runnable my = () -> {
            System.out.println(Singleton.getInstance());
        };*/
    
        MyThread my = new MyThread();
        for(int i=1; i<=5; i++){
            new Thread(my).start();
        }
    }
}

※停一秒鐘,然後 Parallel,就有可能會有2個實體

※註解是 Java8 的 lambda 寫法,此時可以不用 implements Runnable 和實作

※1.設定 msconfig
2.設定 taskmgr,針對java、javaw、Eclipse 使用一顆 CPU,還是一樣的結果,不知道為什麼
理論上單核是不會有併行的


※登記式單例

public class Singleton {
    private Singleton() {}
    
    public static Singleton getInstance() {
        return InnerSingleton.SINGLETON;
    }
    
    private static class InnerSingleton {
        private static final Singleton SINGLETON = new Singleton();
    }
}

※綜合餓漢和懶漢的最佳單例

沒有留言:

張貼留言