源码解读: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(); } }