设计模式之单例模式
2020-12-26 本文已影响0人
逍遥白亦
单例模式
定义
指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。
特点
- 单例类只有一个实例对象
- 该单例对象必须由单例类自行创建;
- 单例类对外提供一个访问该单例的全局访问点;
结构
主要角色
- 单例类:包含一个实例且能自行创建这个实例的类
- 访问类:使用单例的类
类图
实现
懒汉式单例
package Singleton;
/**
* 懒汉式
* 保证只有类在用到时才加载,注意线程安全
* 由于加锁,性能会下降
*/
public class LazySingleton {
private static volatile LazySingleton instance;
private LazySingleton() {};
public static synchronized LazySingleton getInstance(){
if (instance == null){
instance = new LazySingleton();
}
return instance;
}
}
饿汉式单例
package Singleton;
/**
* 饿汉式
* 类加载到内存后,就实例化一个单例,JVM保证线程安全
* 简单实用,推荐使用
* 唯一缺点:不管用到与否,类加载时就完成实例化
*/
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {};
public static HungrySingleton getInstance() {
return instance;
}
public static void main(String[] args){
HungrySingleton h1 = HungrySingleton.getInstance();
HungrySingleton h2 = HungrySingleton.getInstance();
System.out.println(h1 == h2);
}
}
静态内部类实现
package Singleton;
/**
* 静态内部类
* JVM保证单例
* 加载外部类时不会加载内部类,这样可以实现懒加载
*/
public class InnerStaticSingleton {
private InnerStaticSingleton() {};
private static class InnerStaticSingletonHolder{
private static final InnerStaticSingleton INSTANCE = new InnerStaticSingleton();
}
public static InnerStaticSingleton getInstance(){
return InnerStaticSingletonHolder.INSTANCE;
}
public static void main(String[] args){
for (int i=0; i<100; i++){
new Thread( () -> System.out.println(InnerStaticSingleton.getInstance().hashCode())).start();
}
}
}
Java创始人推荐的写法
package Singleton;
/**
* Java创始人之一在Effective in Java中的写法
* 保证线程安全,也保证反序列化,因为枚举类没有构造方法,无法构造出实例
*/
public enum NBSingleton {
INSTANCE;
public static void main(String[] args){
for (int i=0; i<100; i++){
new Thread( () -> System.out.println(NBSingleton.INSTANCE.hashCode())).start();
}
}
}