zoukankan      html  css  js  c++  java
  • 单例、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(); } }
  • 相关阅读:
    PHP图像操作:3D图、缩放、旋转、裁剪、添加水印(三)
    PHP图像操作:3D图、缩放、旋转、裁剪、添加水印(二)
    PHP图像操作:3D图、缩放、旋转、裁剪、添加水印(一)
    问题:关于贴友分类菜单的实现
    jq实现图片轮播:圆形焦点+左右控制+自动轮播
    CSS快速制作图片轮播的焦点
    常用的正则表达式归纳—JavaScript正则表达式
    JQuery插件之图片轮播插件–slideBox
    Javascript时间操作小结
    python第八天)——购物车作业优化完成
  • 原文地址:https://www.cnblogs.com/skyblue123/p/13363165.html
Copyright © 2011-2022 走看看