zoukankan      html  css  js  c++  java
  • 设计模式-单例模式

    单例模式

    定义:用于保证一个类仅有一个实例,并提供别的类访问它的方法。

    使用场景:需要控制实例只能有一个、节省资源的时候。

    常用的创建单例模式的方法有6种。

    1. 懒汉式

    线程不安全、延迟初始化

    public class Singleton {
    
        private Singleton(){}
        
        private static Singleton singleton;
        
        public static Singleton getInstance(){
            if(singleton==null){
                singleton=new Singleton();
            }
            return singleton;
        }
    }
    
    1. 懒汉式(加锁)

    线程安全、延迟初始化

    public class Singleton {
    
        private Singleton(){}
    
        private static Singleton singleton;
    
        public static synchronized Singleton getInstance(){
            if(singleton==null){
                singleton=new Singleton();
            }
            return singleton;
        }
    }
    
    1. 饿汉式

    线程安全、非延迟初始化

    public class Singleton {
    
        private Singleton(){}
    
        private static Singleton singleton=new Singleton();
    
        public static  Singleton getInstance(){
            return singleton;
        }
    }
    
    1. 双检锁(double-check)

    线程安全、延迟初始化

    public class Singleton {
    
        private Singleton(){}
    
        private static Singleton singleton;
    
        public static  Singleton getInstance(){
            if(singleton==null){
                synchronized (Singleton.class){
                    if(singleton==null){
                        singleton=new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    
    1. 静态内部类

    线程安全、延迟初始化

    public class Singleton {
    
    
        private Singleton() {
        }
    
        private static class SingletonHolder {
            private static final Singleton instance = new Singleton();
        }
    
        public static final Singleton getInstance() {
            return SingletonHolder.instance;
        }
    }
    
    1. 枚举

    线程安全、非延迟初始化

    这种方式实现简单,并且不仅避免多线程同步问题,而且防止反序列化重新创建新对象。

    public enum  Singleton {
        INSTANCE;
    }
    

    单例中的bug;反射创建和反序列化创建。

      public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            Singleton instance1 = Singleton.getInstance();
            Constructor<Singleton> declaredConstructor = Singleton.class.getDeclaredConstructor(null);
            //跳过权限检查,加载私有构造器
            declaredConstructor.setAccessible(true);
            Singleton instance2 = declaredConstructor.newInstance();
            System.out.println(instance1);   //com.mmc.springbootstudy.parteen.singleton.Singleton@5ce65a89
            System.out.println(instance2);   //com.mmc.springbootstudy.parteen.singleton.Singleton@25f38edc
        }
    

    如何避免反射创建呢?

    以静态内部类为例,在构造方法中抛异常

    如何避免反序列化?

    定义一个readResolve()方法,直接返回指定对象

    public class Singleton implements Serializable {
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
        private Singleton (){
            if(SingletonHolder.INSTANCE!=null){
                throw new RuntimeException();
            }
        }
        public static final Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    
        //防止反序列化
        private Object readResolve(){
            return getInstance();
        }
    }
    

    一般来说我们使用饿汉方式就行了,如果明确要求要延迟初始化,就使用静态内部类的方式。

    返回目录

    书山有路勤为径,学海无涯苦作舟
  • 相关阅读:
    扫面线模板
    (动态规划、栈)leetcode 84. Largest Rectangle in Histogram, 85. Maximal Rectangle
    tmux 常见命令汇总
    leetcode 221
    leetcode 319 29
    (贪心)leetcode 392. Is Subsequence, 771. Jewels and Stones, 463. Island Perimeter
    leetcode 982 668
    Python import 同文件夹下的py文件的函数,pycharm报错
    Windows里Anaconda-Navigator无法打开的解决方案
    Windows下 gpu版 Tensorflow 安装
  • 原文地址:https://www.cnblogs.com/javammc/p/14938637.html
Copyright © 2011-2022 走看看