当前位置: 代码迷 >> 综合 >> Java 单例模式详解
  详细解决方案

Java 单例模式详解

热度:82   发布时间:2024-02-21 21:59:40.0

一 模式定义

保证一个类只有一个实例,并提供一个全局访问点

 

二 场景

之所以使用单例模式,是因为某些重量级的对象,不需要多个实例,因为占用系统资源过高。例如线程池,数据库连接池。

 

三 两种经典模式

1.懒汉模式

只有在对象使用时才初始化。

举例代码如下:

/*** @author xionglz* @Slogan 致敬大师,致敬未来的你*/class LazySingleton{//使用valatitle防止指令重排序,不使用可能造成空指针异常。private volatile static LazySingleton instance;/*私有构造函数防止其他类创建实例*/private LazySingleton(){}public  static LazySingleton getInstance() {//每次初始化前先判断是否为空if (instance==null){//使用java内置锁保证线程安全synchronized (LazySingleton.class){//双重检查防止重复创建对象保证单例,因为第二个线程拿到锁后,此时对象可能已经创建if (instance==null){/*  创建对象非原子操作JIT可能会进行指令重排,所以需用valatitle创建对象顺序为:1.分配空间2.初始化3.引用赋值*/instance=new LazySingleton();}}}return instance;}
}

 

2.饿汉模式

在类加载的初始化阶段就完成了实例的创建。本质上是利用了jvm的类加载机制保证实例的唯一性。

类加载过程:

 

只有在真正使用对应的类时才会触发初始化。例如启动类所在函数,直接进行new 操作,访问静态属性,静态方法,用反射访问一个类,初始化一个类的子类。

代码如下

class HungrySingleton{private static HungrySingleton instance = new HungrySingleton();private HungrySingleton(){//防止反射创建实例if (HungrySingleton.instance != null) {throw new RuntimeException( " 不允许多个实例。" );}}public static HungrySingleton getInstance() {return instance;}
}

 

四 枚举类型

1.天然不支持反射获取实例

2.通过jvm类加载机制实现