解決多執行緒單例模式的執行緒不安全問題
阿新 • • 發佈:2018-12-31
DCL雙檢查鎖機制
public class MyConfig {
private volatile static MyConfig myConfig = null;//volatile 保證每個執行緒都是從主存中讀取最新的資料
private MyConfig(){
}
public static MyConfig getInstance(){
if(null != myConfig){
}else {
//同步程式碼塊
synchronized (MyConfig.class){
if (null == myConfig){
myConfig = new MyConfig();
}
}
}
return myConfig;
}
}
靜態內建類
public class MyConfig {
private MyConfig(){}
private static class MyConfigHandler{
private static MyConfig myConfig = new MyConfig();
}
public static MyConfig getInstance(){
return MyConfigHandler.myConfig;
}
}
序列化和反序列化
public class MyConfig implements Serializable{
private volatile static MyConfig myConfig = null;//volatile 保證每個執行緒都是從主存中讀取最新的資料
private MyConfig(){
}
public static MyConfig getInstance(){
if (null != myConfig){
}else {
//同步程式碼塊
synchronized (MyConfig.class){
if(null == myConfig){
myConfig = new MyConfig();
}
}
}
return myConfig;
}
//單例類需實現這個方法,readResolve方法應對單例物件被序列化時候
public Object readResolve(){
return getInstance();
}
public static MyConfig getMyConfig(){
try {
MyConfig myConfig = MyConfig.getInstance();
FileOutputStream fileOutputStream = new FileOutputStream(new File("myobject.txt"));
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(myConfig);
objectOutputStream.close();
fileOutputStream.close();
System.out.println(myConfig.hashCode());
}catch (Exception e){
e.printStackTrace();
}
MyConfig myConfig = null;
try {
FileInputStream fileInputStream = new FileInputStream(new File("myobject.txt"));
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
myConfig = (MyConfig) objectInputStream.readObject();
objectInputStream.close();
fileInputStream.close();
System.out.println(myConfig.hashCode());
}catch (Exception e){
e.printStackTrace();
}
return myConfig;
}
}
靜態程式碼塊
public class MyConfig{
private static MyConfig myConfig = null;
private MyConfig(){}
static{
myConfig = new MyConfig();
}
public static MyConfig getInstance(){
return myConfig;
}
}
列舉實現
public class MyConfig {
public enum MyConfigEnum{
connectionFactofry;
private MyConnection myConnection = null;
private MyConfigEnum(){
myConnection = new MyConnection();
}
public MyConnection getMyConnection(){
return myConnection;
}
}
public static MyConnection getConnection(){
return MyConfigEnum.connectionFactofry.getMyConnection();
}
}
public class MyConnection {
public MyConnection(){
}
}