今天再来总结一篇开发中常用的设计模式单例模式,其定义是单例对象的类只能允许一个实例存在,它虽然有多种常见的写法,但是其基本思想不变:
private static
public class SingleInstance {
//饿汉模式线程安全
//step1 :私有化构造器
private SingleInstance() {
}
//step2 :提供私有化静态属性
private static SingleInstance sSingleInstance = new SingleInstance();
//step3 : 通过获取该属性的方法
public static SingleInstance getInstance() {
return sSingleInstance;
}
}
public class SingleInstance {
//懒汉模式
//step1 :私有化构造器
private SingleInstance(){}
//step2 :提供私有化静态属性
private static SingleInstance sInstance;
//step3 : 通过获取该属性的方法
public static SingleInstance getInstance(){
if (sInstance == null) {
sInstance=new SingleInstance();
}
return sInstance;
}
}
通过synchronized
修饰该方法,保证线程安全
synchronized
修饰方法,每次使用时都得同步public class SingleInstance {
//懒汉模式 同步方法
//step1 :私有化构造器
private SingleInstance(){}
//step2 :提供私有化静态属性
private static SingleInstance sInstance;
//step3 : 通过获取该属性的方法 synchronized修饰该方法
public static synchronized SingleInstance getInstance(){
if (sInstance == null) {
sInstance=new SingleInstance();
}
return sInstance;
}
}
通过synchronized
修饰该方法,保证线程安全
public class SingleInstance {
//懒汉模式 同步代码快
//step1 :私有化构造器
private SingleInstance(){}
//step2 :提供私有化静态属性
private static SingleInstance sInstance;
//step3 : 通过获取该属性的方法 synchronized修饰该方法
public static SingleInstance getInstance(){
if (sInstance == null) {
synchronized (SingleInstance.class){
sInstance=new SingleInstance();
}
}
return sInstance;
}
}
优点:实现了懒加载,线程安全,效率高,第一层判null提高了锁机制的使用效率,第二层判null才是真正意义的单例。
public class SingleInstance {
//双重锁
//step1 :私有化构造器
private SingleInstance(){}
//step2 :提供私有化静态属性
private static SingleInstance sInstance;
//step3 : 通过获取该属性的方法 synchronized修饰该方法
public static SingleInstance getInstance(){
if (sInstance == null) {//第一层:保证的多线程只有第一次调用getInstance 的时候才会加锁初始化
synchronized (SingleInstance.class){
if (sInstance==null) {// 第二层 实现了单例模式
sInstance=new SingleInstance();
}
}
}
return sInstance;
}
优点:避免了线程不安全,延迟加载,效率高。
public class SingleInstance {
//静态内部类
//step1 :私有化构造器
private SingleInstance(){}
//step2 :提供私有化静态属性
private static SingleInstance sInstance;
//step3 : 通过获取该属性的方法 synchronized修饰该方法
public static SingleInstance getInstance(){
//只有调用此方法的时候才会初始化单例,实现了懒加载,因为类(Single)的加载只有一次,从而保证了单例
return Single.sInstance;
}
private static class Single{
private static SingleInstance sInstance=new SingleInstance();
}
}
这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。
类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。
优点: 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
优点:
系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。
缺点:
单例类的职责过重,在一定程度上违背了“单一职责原则”。
适用场景: