设计模式(一)单例模式(Singleton)

介绍

特点:只有一个实例对象存在(因为被 private 修饰)。

应用场景:  
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。

实现方法(三种):

名称特点优点缺点
饿汉法在加载类的时候就会创建类的单例,并保存在类中代码简单无法延迟加载,线程不安全,可被人使用反射强行调用构造器
懒汉法不在系统加载时就创建类的单例,而是在第一次使用实例的时候再创建,为保证线程安全,加 synchronized 关键字修饰延迟加载,加 synchronized 关键字后实现线程安全效率低下,可被人使用反射强行调用构造器
双重加锁机制双重判断,先判断单例是否存在,只对不存在的单例进行同步操作延迟加载,JDK 1.5 后线程安全,效率较懒汉高使用 volatile 关键字(修饰的变量不会被本地线程缓存,读写操作直接操作内存决定,会屏蔽虚拟机中的优化代码,运行效率低下)可被人使用反射强行调用构造器
静态内部类法将 Singleton 实例放到一个静态内部类中,静态内部类只会加载一下,Singleton 只实例化一次延迟加载和线程安全需要额外的工作(Serializable、transient、readResolve())来实现序列化,否则每次反序列化一个序列化的对象实例时都会创建一个新的实例,可被人使用反射强行调用构造器
枚举写法(最优)枚举线程安全,防止反射强行调用构造器,自动序列化,防止反序列化时自动创建对象Android平台不推荐使用

饿汉法

class EHSingleton {
    private static EHSingleton ehSingleton = new EHSingleton();
    private EHSingleton() {}
    public static EHSingleton getSingleton() {
        return ehSingleton;
    }
}

懒汉法

class LHSingleton {
    private static LHSingleton lhSingleton = null;
    private LHSingleton() {}
    private static synchronized LHSingleton getLhSingleton() {
        if (lhSingleton == null) {
            lhSingleton = new LHSingleton();
        }
        return lhSingleton;
    }
}

双重加锁机制

class Singleton {
    private static volatile Singleton singleton = null;
    private Singleton() {}
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

静态内部类法

class staticSingleton {
    private static class Holder {
        private static staticSingleton staticSingleton = new staticSingleton();
    }
    private staticSingleton() {}
    public static staticSingleton getSingleton() {
        return Holder.staticSingleton;
    }
}

枚举法

enum enumSingleton {
    INSTANCE;
    private String name;
    public  String getName(){
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

总结:

不同的环境可根据具体情况选择合适的单例模式,但尽量要实现单例的三个要点:
1、保证线程安全
2、延迟加载
3、序列化与反序列化安全
可优选“枚举写法”,JDK 1.5 之前 不适合先选择“双重加锁写法”,Android平台不适宜选择“枚举”。


THE END

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@SokachWang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值