1、单例模式概要
定义: 单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例
单例模式确保系统在运行过程中只会存在一个实例,当遇到需要频繁创建对象或者创建对象会花费较多资源的时候,使用单例模式就尤为重要
单例模式可以解决全局变量的一些缺点,比如可以延迟加载,保证只在使用这个类的时候才创建对象,而不是像全局变量一样在一开始就创建完成
tips: 单例模式的构造器必须是私有的
2、单例模式的写法
1)饿汉式单例(立即加载,线程安全)
public class Singleon1 {
private Singleon1(){}
private static Singleon1 singleon1 = new Singleon1();
public static Singleon1 getSingleon1(){
return singleon1;
}
}
饿汉式单例在程序一开始加载时,就把单例变量创建完毕,饿汉式单例是为了防止线程不安全所开发的一种模式(主要就是为了解决懒汉式单例的线程不同步的问题)
2)懒汉式单例(延迟加载,线程不安全)
public class Singleon2 {
private Singleon2(){}
private static Singleon2 singleon2 = null;
public static Singleon2 getInstance(){
if (singleon2 == null){
singleon2 = new Singleon2();
}
return singleon2;
}
}
懒汉式单例,是最常见的单例模式,但是会出现在多线程下不同步的问题,针对这种情况有两种解决方案,一是使用饿汉式,另一种则是在代码中加入线程同步的关键字
3)懒汉式单例-synchronized(延迟加载,线程安全)
public class Singleon3 {
private Singleon3(){}
private static Singleon3 singleon3 = null;
public static Singleon3 getInstance(){
synchronized (Singleon3.class){
if (singleon3 == null){
singleon3 = new Singleon3();
}
}
return singleon3;
}
}
加了synchronized的懒汉式单例可以保证线程安全,但是运行效率较低,下一个线程获取单例必须等待上一个线程释放锁
4)懒汉式单例-双重检查(延迟加载,线程安全)
public class Singleon4 {
private Singleon4(){}
private volatile static Singleon4 singleon4 = null;
private static Singleon4 getInstance(){
if (singleon4 == null){
synchronized (Singleon4.class){
singleon4 = new Singleon4();
}
}
return singleon4;
}
}
利用volatile和synchronized进行双重检查,只有第一次运行的时候会执行同步代码块,大大提高了单例模式的效率
5)内部静态类单例(线程安全,但是序列化不安全)
public class Singleon5 {
private Singleon5(){}
private static class InnerObject{
private static Singleon5 singleon5 = new Singleon5();
}
public static Singleon5 getInstance(){
return InnerObject.singleon5;
}
}
虽然线程安全,但是序列化不安全(存疑)
3、单例模式总结
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
总的来说单例模式可以完全替代全局变量,使代码更清晰。