天天看點

單例模式的三種方式

餓漢式,由于對象不會變化,是以不存在多線程的問題

/**
 * 餓漢式,不會産生線程并發,但是沒有實作按需加載
 * @author Administrator
 *
 */
public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton (){}
    public static Singleton getInstance() {
	    return instance;
    }
   
}
           

好處:

  1. 不會有多線程的問題
  2. 使用起來簡單

不好:

  1. 一開始就初始化對象,會造成浪費
  2. 一般程式都會按照自己需要進行初始化對象
  3. 引出按需初始化對象的懶加載方式(如下)

懶漢式

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

内部類加上餓漢式實作懶加載

public class Singleton {
	/**  
     * 類級的内部類,也就是靜态的成員式内部類,該内部類的執行個體與外部類的執行個體  
     * 沒有綁定關系,而且隻有被調用到才會裝載,進而實作了延遲加載  
     */  
    private static class SingletonHolder{   
        /**  
         * 靜态初始化器,由JVM來保證線程安全  
         */  
        private static Singleton instance = new Singleton();   
    }   
    /**  
     * 私有化構造方法  
     */  
    private Singleton(){   
    }   
    public static Singleton getInstance(){   
        return SingletonHolder.instance;   
    }  
}
           

多線程檢查代碼

public class ThreadGetObjRun implements Runnable {

	@Override
	public void run() {
		//for(int i = 0;i<10;i++){
			System.out.println("線程ID = "+ Thread.currentThread().getId() + Singleton.getInstance());
		//}
	}
	public static void main(String[] args) {
		ThreadGetObjRun runnable = new  ThreadGetObjRun();
		ThreadGetObjRun runnable1 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable2 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable3 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable4 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable5 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable6 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable7 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable8 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable9 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable10 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable11 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable12 = new  ThreadGetObjRun();
		
		Thread singletonThread = new Thread(runnable);
		Thread singletonThread1 = new Thread(runnable1);
		Thread singletonThread2 = new Thread(runnable2);
		Thread singletonThread3 = new Thread(runnable3);
		Thread singletonThread4 = new Thread(runnable4);
		Thread singletonThread5 = new Thread(runnable5);
		Thread singletonThread6 = new Thread(runnable6);
		Thread singletonThread7 = new Thread(runnable7);
		Thread singletonThread8 = new Thread(runnable8);
		Thread singletonThread9 = new Thread(runnable9);
		Thread singletonThread10 = new Thread(runnable10);
		Thread singletonThread11 = new Thread(runnable11);
		Thread singletonThread12 = new Thread(runnable12);
		singletonThread.start();
		singletonThread1.start();
		singletonThread2.start();
		singletonThread3.start();
		singletonThread4.start();
		singletonThread5.start();
		singletonThread6.start();
		singletonThread7.start();
		singletonThread8.start();
		singletonThread9.start();
		singletonThread10.start();
		singletonThread11.start();
		singletonThread12.start();
	}
}