博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式之神奇的单例模式
阅读量:3915 次
发布时间:2019-05-23

本文共 4927 字,大约阅读时间需要 16 分钟。

定义:单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点

隐藏其所有构造方法

属于创建型模式

常见写法

饿汉式单例
懒汉式单例
注册式单例
ThreadLocal单例

优点:

在内存中只有一个实例,减少了内存开销
可以避免对资源的多重占用
设置全局访问点,严格控制访问

缺点:

没有接口,扩展困难.
如果扩展单例对象,只有修改代码,没有其他途径

总结

1.私有化构造器
2.保证线程安全
3.延迟加载
4.防止序列化和反序列化破坏单例
5.防御反射攻击单例

例子

饿汉式
/** * 优点:执行效率高,没有任何锁 * 缺点:浪费内存,肯能会造成内存浪费 */public class HungrySingleton {
private static final HungrySingleton hungrySingleton = new HungrySingleton(); private HungrySingleton(){
} public static HungrySingleton getHungrySingleton(){
return hungrySingleton; }}
public class HungryStaticSingleton {
private static final HungryStaticSingleton hungryStaticSingleton; static {
hungryStaticSingleton = new HungryStaticSingleton(); } private HungryStaticSingleton(){
}; public static HungryStaticSingleton getInstance(){
return hungryStaticSingleton; }}
懒汉式
/** * 优点:节省了内存 * 缺点:线程不安全,使用synchronized解决,缺点,性能下降 */public class LazySimpleSingleton {
private static LazySimpleSingleton lazySimpleSingleton; private LazySimpleSingleton(){
}; public synchronized static LazySimpleSingleton getInstance(){
if(lazySimpleSingleton == null){
lazySimpleSingleton = new LazySimpleSingleton(); } return lazySimpleSingleton; }}
双重检查
/** * 优点:性能高了,线程安全了 * 缺点:可读性难度加大,不够优雅 */public class LazyDoubleCheckSingletion {
private volatile static LazyDoubleCheckSingletion lazyDoubleCheckSingletion; private LazyDoubleCheckSingletion(){
}; public static LazyDoubleCheckSingletion getInstance(){
//检查是否要阻塞 if(lazyDoubleCheckSingletion == null){
synchronized (LazyDoubleCheckSingletion.class){
//检查是否要重新创建实例 if(lazyDoubleCheckSingletion == null){
lazyDoubleCheckSingletion = new LazyDoubleCheckSingletion(); //指令重排序的问题 } } } return lazyDoubleCheckSingletion; }}
静态内部类
/*  优点:写法优雅,利用了java本身特点,性能高,避免了内存浪费  缺点:能够被反射破坏 */public class LazyStaticInnerClassSingleton {
private LazyStaticInnerClassSingleton(){
}; public static LazyStaticInnerClassSingleton getInstance(){
return LazyHolder.INSTANCE; } private static class LazyHolder{
private static final LazyStaticInnerClassSingleton INSTANCE = new LazyStaticInnerClassSingleton(); }}
/*  优点:利用了java本身特点,性能高,避免了内存浪费,不能反射破坏  缺点:不优雅 */public class LazyStaticInnerClassNoReflectSingleton {
private LazyStaticInnerClassNoReflectSingleton(){
if(LazyHolder.INSTANCE != null){
throw new RuntimeException("不允许非法访问!"); } }; public static LazyStaticInnerClassNoReflectSingleton getInstance(){
return LazyHolder.INSTANCE; } private static class LazyHolder{
private static final LazyStaticInnerClassNoReflectSingleton INSTANCE = new LazyStaticInnerClassNoReflectSingleton(); }}
枚举式
public enum EnumSingleton {
INSTANCE; private Object data; public Object getData() {
return data; } public void setData(Object data) {
this.data = data; } public static EnumSingleton getInstance(){
return INSTANCE;};}
注册式
public class ContainerSingleton {
private ContainerSingleton(){
}; private static Map
ioc = new ConcurrentHashMap<>(); public static Object getInstance(String className){
Object instance = null; if(!ioc.containsKey(className)){
try {
instance = Class.forName(className).newInstance(); ioc.put(className,instance); } catch (InstantiationException e) {
e.printStackTrace(); } catch (IllegalAccessException e) {
e.printStackTrace(); } catch (ClassNotFoundException e) {
e.printStackTrace(); } return instance; }else{
return ioc.get(className); } }}
序列化
public class SeriableSingleton implements Serializable {
//序列化 //把内存中对象的状态转换为字节码的形式 //把字节码通过IO输出流,写到磁盘上 //永久保存下来,持久化 //反序列化 //将持久化的字节码内容,通过IO输入流读取内存中 //转换成java对象 private static final SeriableSingleton INSTANCE = new SeriableSingleton(); private SeriableSingleton(){
} public static SeriableSingleton getInstance(){
return INSTANCE; } private Object readResolve(){
return INSTANCE; }}
本地线程式
public class ThreadLocalSingleton {
private static final ThreadLocal
threadLocalInstance = new ThreadLocal
(){
@Override protected ThreadLocalSingleton initialValue() {
return new ThreadLocalSingleton(); }; }; private ThreadLocalSingleton(){
}; public static ThreadLocalSingleton getInstance(){
return threadLocalInstance.get(); }}

转载地址:http://ukjrn.baihongyu.com/

你可能感兴趣的文章
Firefox 18周岁
查看>>
IdentityServer4系列 | 初识基础知识点
查看>>
自由软件基金会庆祝成立35周年
查看>>
网络知识 | 《图解TCP/IP》读书笔记(下)
查看>>
国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作
查看>>
面试 .NET 开发,为什么也要考算法?
查看>>
BeetleX之TCP消息通讯Protobuf/TLS
查看>>
AA.Dapper升级了
查看>>
C#刷剑指Offer | 二叉树中和为某一值的路径
查看>>
你是个失败者,有什么资格说话?
查看>>
为什么我们总是「习惯性辩解」?
查看>>
.NET 异步解说
查看>>
Magicodes.IE 2.4发布
查看>>
程序员修神之路--它可能是分布式系统中最重要的枢纽
查看>>
如何理解Eating这个词?云原生与微服务专场介绍
查看>>
诊断日志知多少 | DiagnosticSource 在.NET上的应用
查看>>
Chrome正在启用HTTP/3,支持IETF QUIC
查看>>
简单聊聊AspNetCore的启动流程
查看>>
.NET架构小技巧(2)——访问修饰符正确姿势
查看>>
一站式Web开发套件BeetleX.WebFamily
查看>>