美文网首页
单例模式

单例模式

作者: 金煜博 | 来源:发表于2021-05-05 11:20 被阅读0次

什么是单例模式?

保证jvm中只能有一个实例

1.饿汉式

提前创建对象,保证了线程的安全,占内存空间,影响程序启动效率

示例代码

public class Singleton {
    public  static Singleton singleton = new Singleton();
    private Singleton() {
    }
    public static Singleton getInitial(){
        return singleton;
    }
}
public class V1 {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInitial();
        Singleton singleton2 = Singleton.getInitial();
        System.out.println(singleton1==singleton2);
    }
}

2.懒汉式

需要用到时才创建对象实例,因为在方法上加了锁,导致创建和获取对象都上了锁,效率低。

示例代码

public class Singleton {
    private static Singleton singleton;
    //私有的构造方法可以禁止new对象
    private Singleton() {

    }

     //在方法上加锁导致读写操作都上锁了效率低,成了单线程了
     public static synchronized Singleton  getInitial(){
         try {
             Thread.sleep(3000);
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
        if(singleton==null){
            singleton = new Singleton();
        }
        return singleton;
     }
}
public class V2 {
   //创建100个线程模拟执行效率和线程是否安全
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Singleton singleton1 =  Singleton.getInitial();
                    System.out.println(Thread.currentThread().getName()+"-----------"+singleton1);
                }
            }).start();
        }
    }
}

3.双重检验锁

双重检验锁解决了在写上锁,读不上锁,有效的提高执行效率
(重点理解下两个if判断的意义)

示例代码

public class Singleton {
    private static Singleton singleton;
    //私有的构造方法可以禁止new对象
    private Singleton() {

    } 
    //在代码段上加锁,只是在创建Singleton时上锁,读取时无锁。(双重检验锁)
    public static Singleton getInitial() {
        //第一个if判断singleton是否null不是就可以直接读取singleton对象
        if (singleton == null) {
            synchronized (Singleton.class) {
                //第二个if判断防止多个线程同时拿到锁后,重复创建singleton对象
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
public class V2 {
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Singleton singleton1 =  Singleton.getInitial();
                    System.out.println(Thread.currentThread().getName()+"-----------"+singleton1);
                }
            }).start();
        }
    }
}

4.静态类部内

静态内部内结合了懒汉式和饿汉式的优,效率高

示例代码

public class Singleton {
    private Singleton() {
        System.out.println("-----------初始化构造函数-------");
    }

    private static  Singleton initialSingleton(){
        return GetSingleton.singleton;
    }

    private static class GetSingleton{
        private  final  static  Singleton singleton =  new Singleton();
    }

    public static void main(String[] args) {
        System.out.println("开始运行");
        Singleton singleton1 =  Singleton.initialSingleton();
        Singleton singleton2 =  Singleton.initialSingleton();
        System.out.println(singleton1==singleton2);
    }

5.枚举

使用枚举方式可以有效的防止反射机制和序列化,因为jdk底层源码中有if判断禁用了反射与序列化

public enum  Singleton {
    SL;
    public   void show(){
        System.out.println("枚举单例模式可以防止反射和序列化");
    }
}
public class V4 {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.SL;
        Singleton singleton2 = Singleton.SL;
        System.out.println(singleton1 == singleton2);
        singleton1.show();
    }
}

6.单例模式额外注意点

1.使用反射机制可以破解单例
2.使用序列化可以破解单例
3.可以在无参构造方法中判断单例对象是否为null,是就抛出异常
4.不用懒加载的话用饿汉式,反之用静态类部内方式,需要序列化的对象用枚举方式

相关文章

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • 设计模式之单例模式详解

    设计模式之单例模式详解 单例模式写法大全,也许有你不知道的写法 导航 引言 什么是单例? 单例模式作用 单例模式的...

  • Telegram开源项目之单例模式

    NotificationCenter的单例模式 NotificationCenter的单例模式分析 这种单例模式是...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • IOS单例模式的底层原理

    单例介绍 本文源码下载地址 1.什么是单例 说到单例首先要提到单例模式,因为单例模式是单例存在的目的 单例模式是一...

  • 单例

    iOS单例模式iOS之单例模式初探iOS单例详解

  • 单例模式

    单例模式1 单例模式2

  • java的单例模式

    饿汉单例模式 懒汉单例模式

网友评论

      本文标题:单例模式

      本文链接:https://www.haomeiwen.com/subject/qzyfdltx.html