Java单例模式目录
⛳ Java单例模式
概念: java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例。
单例模式:要求程序中某个,再程序运行的整个整个周期中中,只有一个实例。
提供静态方法返回对象实例,返回的是静态实例(静态的特征),所以只有一个实例设计模式:程序再某种场景的,设计和开发套路,比如围棋和象棋套路
单例模式有一下特点:
- 单例类只能有一个实例。
- 单例类必须自己自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
首先看一个经典的单例实现。
public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}
Singleton通过将构造方法限定为private避免了类在外部被实例化,在同一个虚拟机范围内,Singleton的唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Jav单例实现失效。此问题在此处不做讨论,姑且掩耳盗铃地认为反射机制不存在。)
但是以上实现没有考虑线程安全问题。所谓线程安全是指:如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。显然以上实现并不满足线程安全的要求,在并发环境下很可能出现多个Singleton实例。
🐾 一,懒汉模式
/**
* 懒汉模式
*/
public class SingletonLazy {
private SingletonLazy(){
System.out.println("SingletonLazy 对象实例化了");
}
private static SingletonLazy singletonLazy = null;
public static SingletonLazy getInstance(){
if (null == singletonLazy) {
return singletonLazy = new SingletonLazy();
}
return singletonLazy;
}
}
🏭 二,饿汉模式
/**
* 饿汉模式
* - 好处:线程安全的
* - 坏处:加载时,时间比较长
*/
public class SingletonHungry {
// 构造函数私有化
private SingletonHungry(){
System.out.println("SingletonHungry 实例化了");
}
//因为静态的特性只有一份存在方法区,所以这个对象一定只有一个
private static SingletonHungry singletonHungry = new SingletonHungry();
public static SingletonHungry getInstance(){
return singletonHungry;
}
}
📢 三,测试
public class SingletonTest {
public static void main(String[] args) {
System.out.println("--------------饿汉模式---------------");
SingletonHungry singletonHungry1 = SingletonHungry.getInstance();
SingletonHungry singletonHungry2 = SingletonHungry.getInstance();
SingletonHungry singletonHungry3 = SingletonHungry.getInstance();
SingletonHungry singletonHungry4 = SingletonHungry.getInstance();
SingletonHungry singletonHungry5 = SingletonHungry.getInstance();
System.out.println(singletonHungry1);
System.out.println(singletonHungry2);
System.out.println(singletonHungry3);
System.out.println(singletonHungry4);
System.out.println(singletonHungry5);
System.out.println("--------------懒汉模式---------------");
SingletonLazy singletonLazy1 = SingletonLazy.getInstance();
SingletonLazy singletonLazy2 = SingletonLazy.getInstance();
SingletonLazy singletonLazy3 = SingletonLazy.getInstance();
System.out.println(singletonLazy1);
System.out.println(singletonLazy2);
System.out.println(singletonLazy3);
}
}
结果:
--------------饿汉模式---------------
SingletonHungry 实例化了
org.example.day08Model.SingletonHungry@1b6d3586
org.example.day08Model.SingletonHungry@1b6d3586
org.example.day08Model.SingletonHungry@1b6d3586
org.example.day08Model.SingletonHungry@1b6d3586
org.example.day08Model.SingletonHungry@1b6d3586
--------------懒汉模式---------------
SingletonLazy 对象实例化了
org.example.day08Model.SingletonLazy@4554617c
org.example.day08Model.SingletonLazy@4554617c
org.example.day08Model.SingletonLazy@4554617c