6种单例模式
以下所有单例模式将从三个角度分析分别是: 线程是否安全,是否是懒加载,还有效率问题
1.饿汉单例模式
饿汉单例模式:该单例模式是在类加载时进行初始化的
public class Hungry {
/**
* @description: TODO 饿汉单例模式 : 在类加载的时候就将对象实例化出来
* @version 1.0
*/
// 1. 线程安全性 : 实例在类加载时进行的初始化,所以线程是安全的
// 2. 是否懒加载 : 没有进行懒加载,长时间未使用该对象的话,会造成内存的浪费
// 3. 性能 : 性能比较好,因为实例化时间比较早,并可以保证对象的唯一,所以不会对后续造成性能影响
private static Hungry hungry=new Hungry();
public Hungry() {
}
public static Hungry getHungry() {
return hungry;
}
public static void setHungry(Hungry hungry) {
Hungry.hungry = hungry;
}
}
2.懒汉单例模式
懒汉单例模式:该单例模式是在调用时进行实例化的
public class Lazy {
/**
* @description: TODO 懒汉单例模式 : 在使用这个对象时实例化该对象
* @version 1.0
*/
// 1. 线程安全性 : 单线程下没有问题,多线程下可能会生成多个实例,主要问题出现在判断对象为空这一步
// ,多线程时可能多个线程都会得到该对象为空的判断
// 2. 是否懒加载 : 进行了懒加载
// 3. 性能 : 性能比较好,仅仅是指单线程的时候,多线程的时候生成多个对象,就是内存浪费了
private static Lazy lazy = null;
public Lazy() {
}
// TODO 在使用该对象的时候对该对象进行实例化
public static Lazy getLazy() {
if(null == lazy){
lazy = new Lazy();
}
return lazy;
}
public static void setLazy(Lazy lazy) {
Lazy.lazy = lazy;
}
}
3.懒汉同步单例模式
懒汉同步单例模式:该单例模式是在调用时进行实例化的,并且可以保证对象的唯一,使用 synchronized 修饰方法;
public class LazySync {
/**
* @description: TODO 懒汉同步单例模式 : 在使用这个对象时实例化该对象
* @version 1.0
*/
// 1. 线程安全性 : 因为使用 synchronized 修饰了方法,所以是线程安全的
// 2. 是否懒加载 : 进行了懒加载
// 3. 性能 : 性能不好,因为使用 synchronized 修饰方法,会使得多线程退化成串行化执行
private static LazySync lazySync = null;
public LazySync() {
}
public static synchronized LazySync getLazySync() {
if(null == lazySync){
lazySync = new LazySync();
}
return lazySync;
}
public static void setLazySync(LazySync lazySync) {
LazySync.lazySync = lazySync;
}
}
4.DCL+Volatile单例模式
DCL+Volatile单例模式:该模式也是在调用时初始化,可用性比较高
/**
* @ClassName DCLVolatile DCL即Double-Check-Locking,即双重锁,再加上Volatile关键字修饰实例化对象,
* 使程序每次都去读取内存中最新的值,这样可以避免值在对象进行初始化时读取对象结果
* 为null的情况 可用
* @Deacription TODO 单例模式: 多个线程要操作该对象,需要在多个线程操作该对象的时候保证该对象的唯一性
* @Author zsl
* @Date 2021/2/22 15:12
* @Version 1.0
**/
public class DCLVolatile {
/**
* @description: TODO 懒汉DCL+Volatile单例模式 : 在使用这个对象时实例化该对象
* @author zhoushilong
* @version 1.0
*/
// 1. 线程安全性 : 线程是安全的
// 2. 是否懒加载 : 进行了懒加载
// 3. 性能 : 性能比较好
private static volatile DCLVolatile dclVolatile = null;
public DCLVolatile() {
}
public static DCLVolatile getDclVolatile() {
if(null == dclVolatile){
synchronized (DCLVolatile.class){
if(null == dclVolatile){
dclVolatile = new DCLVolatile();
}
}
}
return dclVolatile;
}
public static void setDclVolatile(DCLVolatile dclVolatile) {
DCLVolatile.dclVolatile = dclVolatile;
}
}
5.Holder单例模式
Holder单例模式:利用类加载的机制,来实现懒加载,同时可以保持对象的唯一,拥有很高的可用性
/**
* @ClassName HolderSingLeton Holder模式 利用类加载机制,来保证初始化时只有一个线程,
* 跟懒汉式差别的地方是这个是将实例的初始化放在静态类中实现的懒加载
* @Deacription TODO 单例模式: 多个线程要操作该对象,需要在多个线程操作该对象的时候保证该对象的唯一性
* @Author zsl
* @Date 2021/2/22 16:06
* @Version 1.0
**/
public class HolderSingLeton {
public HolderSingLeton() {
}
/**
* @description: TODO Holder单例模式 : 在使用这个对象时实例化该对象
* @author zhoushilong
* @version 1.0
*/
// 1. 线程安全性 : 线程是安全的
// 2. 是否懒加载 : 进行了懒加载
// 3. 性能 : 性能比较好
public static HolderSingLeton getHolderSingLeton() {
return Holder.holderSingLeton;
}
private static class Holder{
private static HolderSingLeton holderSingLeton = new HolderSingLeton();
}
}
6.枚举单例模式
枚举单例模式:借用枚举类的特性,直接解决了多线程的问题
/**
* @ClassName EnumSingleton 枚举单例模式
* @Deacription TODO
* @Author zsl
* @Date 2021/2/22 16:47
* @Version 1.0
**/
public class EnumSingleton {
public EnumSingleton() {
}
/**
* @description: TODO 枚举单例模式 : 在使用这个对象时实例化该对象
* @author zhoushilong
* @version 1.0
*/
// 1. 线程安全性 : 线程是安全的
// 2. 是否懒加载 : 进行了懒加载
// 3. 性能 : 性能比较好
public static EnumSingleton getEnumSingleton(){
return EnumHolder.ENUMSINGLETON.enumSingleton;
}
private enum EnumHolder{
ENUMSINGLETON;
private EnumSingleton enumSingleton = null;
private EnumHolder(){
enumSingleton = new EnumSingleton();
}
private EnumSingleton getEnumSingleton(){
return enumSingleton;
}
}
}