設計模式:單例模式(十一)

//最近海口出差,但學習還是要堅持。好幾天沒上CSDN了,有點想念。希望有一天,我也能天天敲代碼。。。

//設計模式,不應該是模板,應該是編程思想,學習的本質,不在於記住她,而在於她觸發了你的思想!

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;

public class SingleTest {
	public static void main(String[] args) throws Exception{
		//==================1
		SingleDemo sg=SingleDemo.getInstence();
		SingleDemo sg1=SingleDemo.getInstence();
		System.out.println(sg==sg1);
		//==================2
		/*SingleDemo01 sg2=SingleDemo01.getInstence();
		SingleDemo01 sg21=SingleDemo01.getInstence();
		System.out.println(sg2==sg21);*/
		//=================3
		SingleDemo03 sg3=SingleDemo03.getInstence();
		SingleDemo03 sg31=SingleDemo03.getInstence();
		System.out.println(sg3==sg31);
		//====================
		System.out.println(SingleDemo04.INSTENCE==SingleDemo04.INSTENCE);
		SingleDemo04.INSTENCE.dowith();
		//============通過反射 調用私有構造器
		/*Class<SingleDemo01> cla=(Class<SingleDemo01>) Class.forName("mine.singleton.SingleDemo01");
		Constructor<SingleDemo01> c=cla.getDeclaredConstructor(null);
		c.setAccessible(true);
		SingleDemo01 instence=c.newInstance();*/
		//=======通過序列化    反序列化 創建多個實例
		SingleDemo01 sg2=SingleDemo01.getInstence();
		SingleDemo01 sg21=SingleDemo01.getInstence();
		System.out.println(sg2);
		//=================================
		FileOutputStream fos=new FileOutputStream("D:/1.txt");
		ObjectOutputStream oos=new ObjectOutputStream(fos);
		oos.writeObject(sg2);
		oos.flush();
		oos.close();
		fos.close();
		//=================================
		FileInputStream fis=new FileInputStream(new File("D:/1.txt"));
		ObjectInputStream ois=new ObjectInputStream(fis);
		SingleDemo01 sss=(SingleDemo01) ois.readObject();
		System.out.println(sss);
		ois.close();
		fis.close();
	}
}
/**
 * 單例模式:餓漢式
 * 線程安全 調用效率高
 * 
 */
class SingleDemo{
	//類加載時  天然的線程安全。立即加載,不延時。可能會浪費資源
		private static SingleDemo instence=new SingleDemo(); 
		private SingleDemo(){
		}
		public static SingleDemo getInstence(){
			return instence;
		}
}
/**
 * 單例模式:懶漢式
 * 延時加載 ,真正用的時候才加載。
 * 資源利用率高
 * 同步方法,併發效率低
 */
class SingleDemo01 implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//延時加載,真正用的時候 再加載
	private static SingleDemo01 instence;
	private  SingleDemo01(){
		if(null!=instence){//防止 反射調用 構造器。寫項目一般不需要這樣考慮
			throw new RuntimeException();
		}
	}
	//方法同步,調用效率低
	public static synchronized SingleDemo01 getInstence(){
		if(instence==null){
			instence=new SingleDemo01();
		}
		return instence;
	}
	//==========防止反序列化,生成多個實例
	public Object readResolve(){
		return instence;
	}
}
/**
 * 單例模式:雙重檢測鎖
 * 由於編譯器優化,與jvm底層模型的問題,偶爾會出問題,不建議使用
 */
class SingleDemo02{
	private static SingleDemo02 instence;
	private  SingleDemo02(){}
	public static  SingleDemo02 getInstence(){
		if(instence==null){
			SingleDemo02 sg;
			synchronized(SingleDemo02.class){
				sg=instence;
				if(sg==null){
					synchronized(SingleDemo02.class){
						if(sg==null){
							sg=new SingleDemo02();
						}
					}
					return sg;
				}
			}
		}
		return instence;
	}
}
/**
 * 單例模式:靜態內部類
 * 兼具:併發高效,延時加載,
 * 線程安全
 * 外部類 沒有static屬性,所以不會像餓漢式直接加載
 */
class SingleDemo03{
	private static class SingleInstence{
		//instence是 static final 類型保證了只有這樣一個實例存在,而且只能賦值一次,保證線程安全
		private static final SingleDemo03 instence=new SingleDemo03(); 
	}
	private SingleDemo03(){
	}
	public static SingleDemo03 getInstence(){
		return  SingleInstence.instence;
	}
}
/**
 * 單例模式:枚舉
 * 沒有懶加載
 * 避免了 序列化反序列化和反射的漏洞
 */
enum SingleDemo04{
	INSTENCE;
	//==================
	public void dowith(){
		System.out.println("我是枚舉類型的單實例");
	}
}


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