最近在学习,整理设计模式。将一些个人总结的,学习的,分享出来,如有版权,请联系,会及时删除。
单例模式:
定义:
单例模式用来创建全局唯一的对象。一个类只允许创建一个对象(或者叫实例),那这个类就是一个单例类,这种设计模式就叫做单例模式。
实现方式:
饿汉式:
饿汉式的实现方式,在类加载的期间,就已经将instance静态实例初始化好了,所以,instance实例的创建是线程安全的。不过,这样的实现方式不支持延迟加载实例。
public class Singleton_01 {
//1. 私有构造方法
private Singleton_01(){ }
//2. 在本类中创建私有静态的全局对象
private static Singleton_01 instance = new Singleton_01();
//3. 提供一个全局访问点,供外部获取单例对象
public static Singleton_01 getInstance(){
return instance;
}
}
懒汉式:
相对于饿汉式的优势是支持延迟加载。这种实现方式会导致频繁加锁,释放锁,以及并发度低等问题,频繁的调用会产生性能瓶颈。
懒汉式(线程不安全)
public class Singleton_02 {
//1. 私有构造方法
private Singleton_02(){ }
//2. 在本类中创建私有静态的全局对象
private static Singleton_02 instance;
//3. 通过判断对象是否被初始化,来选择是否创建对象
public static Singleton_02 getInstance(){
if(instance == null){
instance = new Singleton_02();
}
return instance;
}
}
懒汉式(线程安全)
public class Singleton_03 {
//1. 私有构造方法
private Singleton_03(){ }
//2. 在本类中创建私有静态的全局对象
private static Singleton_03 instance;
//3. 通过添加synchronize,保证多线程模式下的单例对象的唯一性
public static synchronized Singleton_03 getInstance(){
if(instance == null){
instance = new Singleton_03();
}
return instance;
}
}
双重校验:
双重校验检测实现方式既支持延迟加载,又支持高并发的单例实现方式。只要instance被创建之后,再调用getInstance()函数都不会进入到加锁逻辑中。所以,这种方式解决了懒汉式并发度低的问题。
public class Singleton_04 {
//使用 volatile保证变量的可见性
private volatile static Singleton_04 instance = null;
private Singleton_04(){ }
//对外提供静态方法获取对象
public static Singleton_04 getInstance(){
//第一次判断,如果instance不为null,不进入抢锁阶段,直接返回实例
if(instance == null){
synchronized (Singleton_04.class){
//抢到锁之后再次进行判断是否为null
if(instance == null){
instance = new Singleton_04();
}
}
}
return instance;
}
}
静态内部类:
利用java的静态内部类来实现单例。这种实现方式,既支持延迟加载,也支持高并发,实现起来也比双重检测简单。
public class Singleton_05 {
private static class SingletonHandler{
private static Singleton_05 instance = new Singleton_05();
}
private Singleton_05(){}
public static Singleton_05 getInstance(){
return SingletonHandler.instance;
}
}
枚举:
最简单的实现方式,基于枚举类型的单例实现。这种实现方式通过Java枚举类型本身的特性,保证了实例创建的线程安全和实例的唯一性(同时阻止了反射和序列化对单例的破坏)。
public enum Singleton_06{
INSTANCE;
private Object data;
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static Singleton_06 getInstance(){
return INSTANCE;
}
}
网友评论