【经典结构】单例模式Singleton

单例模式Singleton

1.含义

单例模式:即一个类只能创建一个实例。
应用场景:程序只有一个类实例,所以可以把频繁实例化并且销毁的对象用单例模式,
比如打印机,一个计算机有多个打印机的时候,只能创建一个实例,避免两个打印作业同时输出到打印机;
比如任务管理器,这就是单例模式;

  • 只有一个实例 --> 不可以从类外new对象 --> 构造器私有化private --> 从类里创建实例;
  • 这个对象供外部使用 --> 该实例的get方法 --> 没有对象,随着类加载 --> 方法声明为static --> 静态只能调静态 --> 该实例也声明为static;

2.实现

2.1 饿汉式

public class Singleton{ //1.私有化构造器; private Singleton(); //2.创建实例;静态; private static Singleton singleton = new Singleton(); //3.获取实例的公共方法;静态; public static Singleton getSinggleton(){ return singleton; } }

特点
多线程安全:是;
lazy初始化:否;
类加载就创建实例,浪费内存;

2.2 懒汉式,线程不安全

public class Singgleton{ private Singleton(); private static Singleton singleton; //延迟创建对象; public static Singleton getSingleton(){ if(singleton == null){ //调用方法的时候没有了再创建; singleton = new Singleton(); } return singleton; } }

特点
多线程安全:否 (当有多个线程操作时,可能会有多个线程都经过if判断语句,就会创建多个实例,造成线程不安全);
lazy初始化:是;

2.3 懒汉式,线程安全

public class Singleton{ private Singleton(); private static Singleton singleton; //给方法加锁; public static synchronized Singleton getSingleton(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }

特点
多线程安全:是
lazy初始化:是
效率:低(每次都只是一个线程拿到锁,调用方法,多个线程无法同时调用方法)

2.4 双重检验锁

public class Singleton{ private Singleton(); //使用volatile声明: //1.禁止指令重排; //2.保证变量修改后对所有线程可见,指示JVM,这个变量是共享且不稳定的,每次用要到主存中去读取; private volatile static Singleton singleton; public static Singleton getSingleton(){ if(singleton == null){ //判断有没有实例化过,没有再进入加锁模式,这样绝大多数的都不会再进入了; synchronized(Singleton.class){ if(singleton == null){ //再判断一次,因为可能有多个线程都经过了前面的ifif不判断就会创建多个对象了; singleton == new Singleton(); } } } return singleton; } }

多线程安全:是
lazy初始化:是
效率:高

  • 第一个检验是为了效率;
  • 第二个检验为了线程安全;

2.5内部类

创建一个静态内部类,这样就可以随着类的加载而加载;

public class Singleton{ private Singleton(); private static class SingletonInner{ private static Singleton singleton = new Singleton(); } public static Singleton getSingleton(){ return SingletonInner.sinleton; } }

直接加锁再判断 --> 效率低;
先判断再加锁 --> 效率高;


__EOF__

本文作者Curryxin
本文链接https://www.cnblogs.com/Curryxin/p/15036762.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Curryxin  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
Live2D
欢迎阅读『【经典结构】单例模式Singleton』
点击右上角即可分享
微信分享提示