设计模式——单例模式

单例模式就是某个类只能创建出一个实例对象,这就是单例模式。

1.单例模式的特点

  • 单例类只能创建出一个实例对象。
  • 该实例对象必须由单例类内部自行来创建。
  • 单例类内部必须提供获取实例对象的接口。

2.单例模式的实现方式

2.1饿汉式单例

字如其意,说明急切的需要此类的实例对象,实现方式就是定义私有的静态成员变量,在类加载时就初始化对象,后面多个线程都获取到的是这个唯一的对象,也就不会存在线程安全的问题。

java 复制代码
public class Window {

      //饿汉式单例, 静态的成员在类被加载时,就会初始化window对象,只有一份
      //没有任何的线程安全问题
      private static  Window  window = new Window();

      private Window(){

      }

      public static Window getWindow(){

            return window;
      }

}

2.懒汉式单例

懒汉式单例指的是在调用方法时才会创建对象,所以这种会存在线程安全的问题。

初始懒汉式单例:

java 复制代码
public class Window1 {


      private static Window1 window=null;

      private Window1(){

      }

      /*
           在多线程访问时,可能会有多个线程同时进行到if,就会创建出多个对象
       */
      public static Window1 getWindow(){
            if(window==null){
                  window = new Window1();
            }
            return window;
      }

}

在高并发的情况下,可能同一时间有多个线程同时进入到if判断,就会创建出多个对象。

Synchronized改进:

java 复制代码
public class Window2 {


      private static Window2 window=null;

      private Window2(){

      }

      /*
        给方法加锁, 可以解决,但是效率低,一次只能有一个线程进入获取
       */
      public static synchronized Window2 getWindow(){

            if(window==null){
              window = new Window2();
            }
            return window;
      }

}

最简单粗暴的方式就是在方法上用Synchronized关键字修饰,但这样效率太低了,同一时间只能有一个线程访问此方法。

Synchronized再改进:

java 复制代码
public class Window3 {


      private static Window3 window=null;

      private Window3(){

      }

      /*
           给代码块加锁,双重检索+synchronized
       */
      public static Window3 getWindow(){
            if(window==null){
                  synchronized(Window3.class){
                       if(window == null){
                             window  = new Window3();
                       }
                  }
            }
            return window;
      }
}

改进措施就是双重检索,同一时间可以让多个线程进入第一个if判断,这样保证了效率,然后加锁,代码块内部进行第二个if判断,除了第一个进入的线程,之后已经进入第一个if判断的线程获取到锁时,再次判断发现已经不为null了,就直接返回即可。

volatile+Synchronized:

在并发编程我们了解到,程序可能会出现指令重排的问题,所以为了保险起见我们可以给引用变量加上volatile。

java 复制代码
public class Window {


      private static volatile  Window  window=null;

      private Window(){

      }

      public static  Window getWindow(){
            if(window==null){
                  synchronized(Window.class){
                       if(window == null){
                             window  = new Window();
                       }
                  }
            }
            return window;
      }

}

3.单例模式的应用

Java中的Runtime类就是单例类,利用此类可以用来获取内存空间,释放空间等等。

相关推荐
S***26751 小时前
基于SpringBoot和Leaflet的行政区划地图掩膜效果实战
java·spring boot·后端
马剑威(威哥爱编程)1 小时前
鸿蒙6开发视频播放器的屏幕方向适配问题
java·音视频·harmonyos
JIngJaneIL2 小时前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助
V***u4532 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
这是程序猿2 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
i***t9193 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
k***08293 小时前
【监控】spring actuator源码速读
java·spring boot·spring
麦麦鸡腿堡3 小时前
Java_网络编程_InetAddress类与Socket类
java·服务器·网络
vx_dmxq2113 小时前
【PHP考研互助系统】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·mysql·考研·微信小程序·小程序·php
5***g2983 小时前
新手如何快速搭建一个Springboot项目
java·spring boot·后端