1. 程式人生 > 實用技巧 >單例、readResolve原始碼解讀

單例、readResolve原始碼解讀

https://www.jianshu.com/p/d6fef5b9fbe5

package com.ma.DesignPatterns;

import com.ma.Utils.IOUtil;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @Classname Singleton
 * @Description 單例模式:指一個類只有一個例項,且該類能自行建立這個例項的一種模式。構造器私有,
 *              提供公共的方法getInstance()來建立物件,可能存在反射和反序列化不安全的問題。
 * @Date 2020/6/25 21:00
 * @Created by Fearless
 
*/ public class Singleton implements Serializable { //懶漢式:某些編譯器可能發生指令重排,先instance指向記憶體空間,後初始化物件,導致後來的執行緒會獲得未初始化的物件 /*private static volatile Singleton instance; //避免指令重排 private Singleton(){ //利用異常保證反射安全 if (Singleton.instance != null){ throw new IllegalStateException("該物件已建立!"); } } public static Singleton getInstance(){ //同步程式碼塊,doubleChecking保證執行緒安全 if (instance == null){ synchronized (Singleton.class){ if (instance == null){ instance = new Singleton(); System.out.println("已建立!"); } } } return instance; }
*/ //餓漢式 /*private static Singleton instance = new Singleton(); private Singleton(){ //利用異常保證反射安全 if (Singleton.instance != null){ throw new IllegalStateException("該物件已建立!"); } } public static Singleton getInstance(){ return instance; } private Object readResolve(){ return SingletonHolder.instance; }
*/ //靜態內部類(餓漢式的增強版) /*private static class SingletonHolder{ private static Singleton instance = new Singleton(); } private Singleton(){ //利用異常保證反射安全 if (SingletonHolder.instance != null){ throw new IllegalStateException("該物件已建立!"); } } public static Singleton getInstance(){ return SingletonHolder.instance; } private Object readResolve(){ return SingletonHolder.instance; }*/ //列舉:反射和反序列化均是安全的 /*enum Singleton4{ INSTANCE{ @Override public void doSomething() { System.out.println("建立成功!"); } }; public abstract void doSomething(); }*/ //ThreadLocal:多執行緒中可以保證當前執行緒內的物件是單例模式的,但是不同執行緒中無法保證 /*private static ThreadLocal<Singleton> threadLocal = new ThreadLocal<>(); private static Singleton instance = null; private Singleton(){} public static Singleton getInstance(){ //第一次訪問則進入if語句塊,否則直接返回threadLocal中的物件 if (instance == null){ synchronized (Singleton.class){ if (instance == null){//判斷單例是否建立 instance = new Singleton(); threadLocal.set(instance); } } } return threadLocal.get(); }*/ public static void main(String[] args) throws Exception { /*Singleton s1 = Singleton.getInstance(); Class aClass = s1.getClass(); Constructor constructor = aClass.getDeclaredConstructor(); //設定私有方法訪問許可權 constructor.setAccessible(true); Singleton s2 = (Singleton) constructor.newInstance(); System.out.println(s1 == s2);*/ // IOUtil.serialize(s1); /*Singleton s2 = (Singleton)IOUtil.unserialize(); Singleton s3 = (Singleton)IOUtil.unserialize(); System.out.println(s1 == s2); System.out.println(s3 == s2);*/ //測試列舉 /*Singleton4 s1 = Singleton4.INSTANCE; Singleton4 s2 = Singleton4.INSTANCE; System.out.println(s2 == s1); */ /*Singleton4 s1 = Singleton4.INSTANCE; IOUtil.serialize(s1); Singleton4 s3 = (Singleton4) IOUtil.unserialize(); Singleton4 s4 = (Singleton4) IOUtil.unserialize(); System.out.println(s1 == s3); System.out.println(s3 == s4);*/ //驗證靜態內部類反射是否安全 /*Class<?> aClass = Class.forName("com.ma.DesignPatterns.Singleton"); Constructor<?> constructor = aClass.getDeclaredConstructor(); constructor.setAccessible(true); Singleton s1 = (Singleton)constructor.newInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2);*/ //ThreadLocal測試 /*Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1 == s2); System.out.println(s1);*/ /*for (int i=0;i<10;i++){ new Thread(()->{ Singleton s3 = Singleton.getInstance(); Singleton s4 = Singleton.getInstance(); System.out.println(Thread.currentThread()+"s:"+s3+(s3==s4)); }).start(); }*/ //阻塞主執行緒 System.in.read(); } }