懶漢模式餓漢模式優化

1、餓漢模式

 餓漢模式
    直接在類加載的時候就創建對象
    優點:
         線程安全,獲取對象效率高
    缺點:
         佔用空間,類加載效率低

public class EHanPattern {
	
	private static final EHanPattern INSTANCE=new EHanPattern();
	
	private EHanPattern(){
		
	}
	
	public static EHanPattern getInstance(){
		return INSTANCE;
	}

}

需要優化啓動速度,我們可以用哪個靜態代碼塊優化,讓其在需要的時候創建對象。

public class EHanPatternOptimizing {
	
	private static final EHanPatternOptimizing INSTANCE;
	
	static{
		INSTANCE=new  EHanPatternOptimizing();

	}
	
	private EHanPatternOptimizing(){
		
	}
	
	public static EHanPatternOptimizing getInstance(){
		return INSTANCE;
	}

}

2、懶漢模式

          優點:
             節省空間,啓動速度快,
          缺點:
              線程不安全,獲取對象效率低
  

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

}

優化:雙重校驗鎖,優化的時線程安全問題

public class LanHanPatternOptimizing {
	
	private static LanHanPatternOptimizing instance=null;
	
	private LanHanPatternOptimizing(){
		
	}
	
	public static LanHanPatternOptimizing getInstance(){
		if(instance==null){
			try {
			synchronized (int.class) {
				if(instance==null){
					instance= new LanHanPatternOptimizing();
				}
			}
		}
		
		return instance;
	}

}

3、多線程測試懶漢到底怎麼不安全

改寫懶漢模式在其中加入延時方法用於模擬中間有很多代碼程序的運行、

public class LanHanPattern {
	
	private static LanHanPattern instance=null;
	
	private LanHanPattern(){
		
	}
	
	public static LanHanPattern getInstance(){
		if(instance==null){
			try {
				Thread.sleep(100); //延時用於模擬中間很多代碼
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			instance=new LanHanPattern();
		}
		
		return instance;
	}
}

創建線程類用於比較創建的單例是否相等

public class SingletonThread  extends Thread{
	
	public static LanHanPattern lanhan1;
	public static LanHanPattern lanhan2;
	
	@Override
	public void run() {
		LanHanPattern lanhan1=LanHanPattern.getInstance();
		try {
			Thread.sleep(100); //延時0.1S
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		LanHanPattern lanhan2=LanHanPattern.getInstance();
		if(lanhan1!=null && lanhan2!=null){
			if(lanhan1!=lanhan2){
				System.out.println("false 線程不安全");
			}
		}
	}

}

只要打印出線程不安全,就說明創建的對象時不等的,下面我們來創建測試類

@Test/*測試懶漢*/
public void testLanHanPattern() {
			
	/*每一次創建10000個線程*/
	for(int j=0;j<10000;j++){
		new SingletonThread().start();
	}
		
	System.out.println("true 線程安全");
}

輸出結果:

創建了1w個線程,大概有報了2000多次線程不安全

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章