什么是单例设计模式
- 采用一定的方法保证整个软件系统中,某个类只能存在一个对象实例
实现单例设计模式七种方法(保证安全)
- 1、饿汉式 (静态常量)
/**
* 1、饿汉式 (静态常量)
*/
public class Singleton_1 {
//构造器私有化
private Singleton_1 () {
}
//类加载的时候直接将对象new 出来
private static Singleton_1 instance = new Singleton_1();
//对外提供获取的实例的静态方法
public static Singleton_1 getInstance () {
return instance;
}
}
- 2、饿汉式 (静态代码块)
/**
* 饿汉式 (静态代码块)
*/
public class Singleton_2 {
//构造器私有化
private Singleton_2 () {
}
private static Singleton_2 instance;
//静态代码块 ,类初始化时候,new 出对象实例instance
static {
instance = new Singleton_2();
}
//对外提供获取的实例的静态方法
public static Singleton_2 getInstance () {
return instance;
}
}
-
饿汉式的优缺点
- 优点 : 由于类加载new 出对象,类加载是安全的
- 缺点 : 没有达到延迟加载的效果,可能会造成一个实例内存空间的浪费
-
3、懒汉式(同步方法)
- 能保证延迟加载,安全
- 性能太差
/**
* 懒汉式,同步方法
*/
public class Singleton_3 {
//构造器私有化
private Singleton_3 () {
}
private static Singleton_3 instance;
//对外提供获取的实例的静态方法
public static synchronized Singleton_3 getInstance () {
if (instance == null) {
instance = new Singleton_3();
}
return instance;
}
}
- 4、懒汉式,同步代码块
- 能保证延迟加载,安全
- 性能太差
/**
* 懒汉式,同步代码块
*/
public class Singleton_4 {
//构造器私有化
private Singleton_4 () {
}
private static Singleton_4 instance;
//对外提供获取的实例的静态方法
public static Singleton_4 getInstance () {
synchronized (Singleton_4.class) {
if (instance == null) {
instance = new Singleton_4();
}
}
return instance;
}
}
- 5、懒加载,双重判断机制 (推荐使用)
- 保证懒加载
- 性能很高
/**
* 懒加载,双重判断,性能最佳
*/
public class Singleton_5 {
//构造器私有化
private Singleton_5 () {
}
//volatile 禁止指令重排
private static volatile Singleton_5 instance;
//对外提供获取的实例的静态方法
public static Singleton_5 getInstance () {
//第一次判断,当instance不为空,直接获取,不用走同步代码块
if (instance == null) {
//当instance为空,开始创建,加锁,保证只有一个线程进行创建
synchronized (Singleton_5.class) {
//假如一个线程创建好了,另外一个线程进来,再判断一次,保证安全
if (instance != null) {
instance = new Singleton_5();
}
}
}
return instance;
}
}
- 6、静态内部类 (推荐)
- 延迟加载,线程安全
- 性能也高
/**
* 静态内部类
*/
public class Singleton_6 {
//构造器私有化
private Singleton_6 () {
}
//静态内部类
static class Instance {
static final Singleton_6 INSTANCE = new Singleton_6();
}
//对外提供获取的实例的静态方法
public static Singleton_6 getInstance () {
//静态内部类加载,保证延迟加载,线程安全
return Instance.INSTANCE;
}
}
7 、枚举 (推荐)
/**
* 枚举
*/
public enum Singleton {
INSTANCE;
}
在JDK源码中的应用举例
单例设计模式的使用场景
- 需要频繁进行创建和销毁的对象
- 工具类对象
- 频繁访问数据库或者文件对象 (比如数据源,sessionFactory等)
单例模式在Jdk中的应用
在Runtime 因为这个类 在程序中肯定会被使用到,所以采用了单例模式的饿汉式