-
单例模式 singleton
参考:
https://blog.csdn.net/wayne_lee_lwc/article/details/104228469?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-8.no_search_link&spm=1001.2101.3001.4242.8
模式定义:保障一个类只有一个实例,并且提供一个全局访问点(外部不能进行实例化,内部需要实例化一个私有对象),构造方法私有
典型应用:线程池,数据库连接池,各种managr(mgr) 各种factory ThreadLocal多线程应用
一般使用spring的bean工厂进行保障
实现:
1.饿汉模式:一上来就把对象给new好了,你来了就直接可以拿去吃了,JVM保障每种class只load一次,final是不可变对象(内部成员变量值(引用所指向的地址)不会被改变,因为没有set方法,string都是final的)
public class Singleton1 { private static final Singleton1 uniqueInstance = new Singleton1(); //final必须初始化 private Singleton1(){} public static Singleton1 getInstance() { return uniqueInstance; } }优点:不用考虑线程问题
缺点:类进行加载时便进行了实例化,浪费内存
2.饿汉模式,静态代码块写法:
public class Singleton2 { private Singleton2(){}; private static Singleton2 uniqueInstance; static { uniqueInstance = new Singleton2(); } public static Singleton2 getInstance(){ return uniqueInstance; } }特点:在装载类时,在初始化顺序上先静态变量后静态代码块,所以写法和上一个相同,相当于将定义和初始化分开写的静态版本,优缺点相同
3.懒汉模式,线程不安全型:一开始懒,不创建对象,等你来找我,我再给你创建一个对象,线程不安全型
public class Singleton3 { private Singleton3(){} private static Singleton3 uniqueInstance; public static Singleton3 getInstance() { if(uniqueInstance == null) { uniqueInstance = new Singleton3(); } return uniqueInstance; } }优点:避免过早实例化占用内存,
缺点:在if语句这里线程不安全,可能出现多个实例对象
4.懒汉模式,线程安全型:在获取对象方法前增加synchronized来实现该方法的线程同步,保障线程安全
public class Singleton4 { private Singleton4(){} private static Singleton4 uniqueInstance; public static synchronized Singleton4 getInstance() { if(uniqueInstance == null) { uniqueInstance = new Singleton4(); } return uniqueInstance; } }优点:线程安全
缺点:在线程同步过程中造成不小的延迟,问题:有多少延迟?,仍有改进余地
5.懒汉模式,双重检查型:为减小延迟,提高效率,将同步从对方法转为对类,缩小同步代码块,加入两重判断防止重复进入,同时对对象加上volatile关键字修饰(可以粗浅理解为一个轻量的synchronized,在线程中每次操作都对变量的值进行重读)
参考:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
volatile 关键字用来解决指令重排序问题
public class Singleton5 {
private static volatile Singleton5 uniqueInstance;
private Singleton5(){}
public static Singleton5 getInstance()
{
if(uniqueInstance == null)
{
synchronized(Singleton5.class){
if(uniqueInstance == null)
{
uniqueInstance = new Singleton5();
}
}
}
return uniqueInstance;
}
}
优点:保障线程安全和懒加载,是实际应用中常用的推荐写法
缺点:无
6.懒汉模式,静态内部类型:该设计十分巧妙,将对象定义在静态内部类中,由于内部静态类不随类加载,且加载时线程安全特性,所以将懒加载,线程安全,效率问题一并解决,JVM保障每种class只load一次
public class Singleton6 {
private Singleton6(){}
private static class LazyHolder
{
private final static Singleton6 uniqueInstance = new Singleton6();
}
public static Singleton6 getInstance()
{
return LazyHolder.uniqueInstance;
}
}
优点:回归最初的简易逻辑,更简洁,没有性能损耗,是实际使用时常用的推荐写法
缺点:无
7.枚举单例:Java圣经《Effective Java》中,Joshua Bloch提供的方法,最完美的方法,根因是:枚举类没有构建方法,枚举类在字节码层面是abstract class
参考:https://www.jianshu.com/p/d9d9dcf23359
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("doSomething");
}
}
调用方法:
public class Main {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
直接通过Singleton.INSTANCE.doSomething()的方式调用即可。方便、简洁又安全。
优点:可以防御反射调用和序列化攻击,最完美的方法
缺点:无



