单例、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(); } }

 

posted @ 2020-07-22 21:10  轻风青枫  阅读(233)  评论(0编辑  收藏  举报