设计模式一(单例模式)

主要思路:将构造方法私有化,并对外提供一个static的方法来创建对象

饿汉式单例

public class Hungry {
​
    private Hungry(){
​
    }
    private final static Hungry hungry = new Hungry();
    public static Hungry getInstance(){
        return hungry;
    }
​
    public static void main(String[] args) {
        Hungry hungry1 = Hungry.getInstance();
        Hungry hungry2 = hungry.getInstance();
        System.out.println(hungry1==hungry2);//true
    }
}

缺点:一开始就创建对象,占用系统资源

懒汉式单例

public class Lazy {
​
    private Lazy(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }
​
    private static Lazy lazy;
​
    public static Lazy getInstance(){
        if(lazy==null){
            lazy = new Lazy();
        }
        return lazy;
    }
​
    public static void main(String[] args) {
       for(int i=0;i<10;i++){
           new Thread(()->{
               Lazy.getInstance();
           }).start();
       }
    }
}
​

单线程下不会出现问题,但多线程会会有并发问题,main方法的测试结果:

Thread-0ok
Thread-2ok
Thread-3ok

会发生同一时间创建了多个对象,所以出现了DCL双重检索

DCL懒汉式

public class Lazy {
​
    private Lazy(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }
​
    private volatile static Lazy lazy; //volatile保证不会出现代码重排
​
    public static Lazy getInstance(){
        if(lazy==null) {
            synchronized (Lazy.class) {
                if (lazy == null) {
                    lazy = new Lazy();
                    /*
                        这个过程不是一个原子性,会出现代码重排现象
                        1.开配空间
                        2.执行构造方法
                        3.引用执行
                     */
                }
            }
        }
        return lazy;
    }
​
    public static void main(String[] args) {
       for(int i=0;i<10;i++){
           new Thread(()->{
               Lazy.getInstance();
           }).start();
       }
    }
}

可以实现延迟实例化,并且是线程安全的

静态内部类

public class Holder {
    private Holder(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }
​
    public static Holder getInstance(){
        return InnerClass.holder;
    }
​
    public static class InnerClass{
        private static final Holder holder = new Holder();
    }
​
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                Holder.getInstance();
            }).start();
        }
    }
}

反射破解单例模式

可以采用额外的变量进行控制,防止反射

public class Lazy {
​
    private Lazy(){
        synchronized (Lazy.class){
            if(temp == false){
                temp = true;
            }else{
                throw new RuntimeException("不要用反射破坏单例");
            }
        }
    }
​
    private volatile static Lazy lazy; //volatile保证不会出现代码重排
​
    public static Lazy getInstance(){
        if(lazy==null) {
            synchronized (Lazy.class) {
                if (lazy == null) {
                    lazy = new Lazy();
                    /*
                        这个过程不是一个原子性,会出现代码重排现象
                        1.开配空间
                        2.执行构造方法
                        3.引用指向
                     */
                }
            }
        }
        return lazy;
    }
​
    public static void main(String[] args) throws Exception {
        Lazy lazy = Lazy.getInstance();
        Constructor<Lazy> declaredConstructor = Lazy.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);
        Lazy lazy1 = declaredConstructor.newInstance();
        System.out.println(lazy==lazy1);
    }
}

枚举单例

防止反射破坏

public enum EnumSingleton {
    INSTANCE;
    private EnumSingleton() {
​
    }
​
    public EnumSingleton getInstance(){
        return INSTANCE;
    }
​
    public static void main(String[] args) throws Exception {
        EnumSingleton instance = EnumSingleton.INSTANCE;
        Constructor<EnumSingleton> declaredConstructor = EnumSingleton.class.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        EnumSingleton instance1 = declaredConstructor.newInstance();
        System.out.println(instance==instance1);
    }
}

防止反序列化破坏

重写readResolve()方法

private Object readResolve() throws ObjectStreamException{
        return singleton;
}

相关推荐

  1. 设计模式(模式)

    2024-01-23 13:26:01       36 阅读
  2. 设计模式模式

    2024-01-23 13:26:01       27 阅读
  3. 系列设计模式

    2024-01-23 13:26:01       34 阅读
  4. 设计模式

    2024-01-23 13:26:01       39 阅读
  5. 设计模式

    2024-01-23 13:26:01       20 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-23 13:26:01       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-23 13:26:01       20 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-23 13:26:01       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-23 13:26:01       20 阅读

热门阅读

  1. [自用代码]基于LSTM的广州车牌售价预测

    2024-01-23 13:26:01       30 阅读
  2. 给编译好的so修改rpath为当前路径

    2024-01-23 13:26:01       34 阅读
  3. Linux Wine安装微信记录

    2024-01-23 13:26:01       39 阅读
  4. 定制 APP 开发:满足独特业务需求的最佳选择

    2024-01-23 13:26:01       38 阅读
  5. VC++创建线程学习1

    2024-01-23 13:26:01       40 阅读
  6. Fitten Code:VSCode插件市场的璀璨之星

    2024-01-23 13:26:01       37 阅读
  7. linux命令总结之seq命令

    2024-01-23 13:26:01       35 阅读
  8. 122 解二叉树的右视图的两种方式

    2024-01-23 13:26:01       32 阅读
  9. c++学习理解之路——基类指针指向子类

    2024-01-23 13:26:01       35 阅读
  10. GaussDB如何创建和管理序列、定时任务

    2024-01-23 13:26:01       30 阅读
  11. LeeCode 3. 无重复字符的最长子串

    2024-01-23 13:26:01       28 阅读