一文带你摸清设计模式之单例模式!
- 2022 年 6 月 4 日
- 筆記
本文将给大家介绍java中设计模式——单例模式;
单例模式:保证在⼀个JVM中,该对象只有⼀个实例存在;
适⽤场景:
1、某些类创建⽐较频繁,对于⼀些⼤型的对象,这是⼀笔很⼤的系统开销。
2、省去了new操作符,降低了系统内存的使⽤频率,减轻GC压⼒。
3、有些类如交易所的核⼼交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(⽐如⼀个军队出现了多个司 令员同时指挥,肯定会乱成⼀团),所以只有使⽤单例模式,才能保证核⼼交易服务器独⽴控制整个流程。
代码:
1 public class Singleton{ 2 //持有私有静态实例,防止被引用,赋值为null,目的就是实现延迟加载 3 private static Singleton instance = null; 4 5 6 //私有构造方法,防止被实例化。 7 private Singleton(){ 8 } 9 10 //创建实例 11 public static Singleton getInstance() 12 { 13 if (instance=null){ 14 instance=new Singleton(); 15 16 } 17 return instance; 18 //如果该对象被⽤于序列化,可以保证对象在序列化前后保持⼀致 19 public Object readReaslove(){ 20 return instance; 21 } 22 23 } 24 }
分类:
1.饿汉式:类初始化时创建单例,线程安全,但占用内存空间大,适⽤于占内存⼩的场景,否则推荐使⽤懒汉式延迟加载;
public class Singleton{
private static Singleton instance = new Singleton();
//构造器私有, 外部就无法new这个对象,保证一个类中只有一个实例对象
private Singleton(){}
public static Singleton newInstance(){ return instance; } }
2.懒汉式:需要单例实例的时候再创建,需要考虑线程安全(性能不太好)
1 public class Singleton{ 2 private static Singleton instance = null;//定义一个静态变量指向自己 3 private Singleton(){}//私有化构造方法 4 public static synchronized Singleton newInstance(){//加锁, 5 if (instance == null){ 6 instance = new Singleton(); 7 } 8 } 9 return instance; 10 11 }
3.双重检验锁:假如两个线程A、B,A执⾏了if (instance == null)语句,它会认为单例对象没有创建,此时线程切到B也执⾏了同样的语句,B也认为单例对象没有创建,然后两个线程依次执⾏同步代码块,并分别创建了⼀个单例对象。
1 public class Singleton{ 2 private static volatile Singleton instance = null; 3 private Singleton(){} 4 public static Singleton getInstance(){ 5 if (instance == null) 6 { synchronized (Singleton.class){ 7 if (instance == null){ 8 instance = new Singleton(); 9 10 } 11 } 12 } 13 return instance; 14 }
4.静态内部类:可以同时保证延迟加载和线程安全。静态内部类单例是如何实现懒加载的呢?(懒加载 :使⽤的时候再创建对象)⾸先,我们先了解下类的加载时机。
1 public class Singleton{ 2 private Singleton(){}//私有化构造方法 3 public static Singleton getInstance(){//对外提供获取实例的公共方法 4 return InnerClass.Instance;} 5 private static class InnerClass{//定义静态内部类 6 private final static Singleton Instance=new Singleton; 7 8 } 9 10 }
5.枚举:
1 public enum Singleton{ 2 instance; 3 public void whateverMethod(){} 4 }