執行緒安全單例設計模式+序列化
阿新 • • 發佈:2018-11-03
懶漢式單例模式會引來執行緒安全問題,即多執行緒時可能會建立多個例項,而且在反序列化時也可能會建立新的例項。看了大大們的實現方式,覺得以下一種比較簡單方便理解。
一、下面是會造成執行緒安全的餓漢單例模式。用四列印下會發現hashcode不一致
public class Singleton { private static Singleton instance = null; //禁止new private Singleton(){} public static Singleton getInstance() { if(instance == null){//懶漢式 instance = new MySingleton(); } return instance; } }
二、靜態程式碼塊中的程式碼在使用類的時候就已經執行了,所以可以應用靜態程式碼塊的這個特性實現單例設計模式。
public class Singleton implements Serializable{ private static final long serialVersionUID = 1L; private static Singleton instance = null;//餓漢式 //靜態程式碼塊實現單例模式執行緒安全 static { instance = new Singleton(); } public static Singleton getSingleton() { if (instance == null) { instance = new Singleton(); } return instance; } //該方法在反序列化時會被呼叫 protected Object readResolve() throws ObjectStreamException { System.out.println("呼叫了readResolve方法!"); return Singleton.instance; } }
三、多執行緒呼叫列印例項的hashCode
public class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Singleton.getSingleton().hashCode()); } } public static void main(String[] args) throws Exception { MyThread[] mts = new MyThread[3]; for (int i = 0; i < mts.length; i++) { mts[i] = new MyThread(); } for (int j = 0; j < mts.length; j++) { mts[j].start(); } } }
四、列印序列化和反序列後例項的hashcode
/**
* java類簡單作用描述
*
* @Author: Sosmmh
* @CreateDate: 2018/2/27 10:56
**/
public class SaveAndReadForSingleton {
public static void main(String[] args) {
Singleton singleton = Singleton.getSingleton();
File file = new File("MySingleton.txt");
try {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(singleton);
fos.close();
oos.close();
System.out.println(singleton.hashCode());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
Singleton rSingleton = (Singleton) ois.readObject();
fis.close();
ois.close();
System.out.println(rSingleton.hashCode());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
詳細介紹請看原文大大。
詳細介紹單例模式