一:静态内部类实现单例模式

原理:通过一个静态内部类定义一个静态变量来持有当前类实例,在类加载时就创建好,在使用时获取。

缺点:无法做到延迟创建对象,在类加载时进行创建会导致初始化时间变长。

public classSingletonInner {private static classHolder {private static SingletonInner singleton = newSingletonInner();

}privateSingletonInner(){}public staticSingletonInner getSingleton(){returnHolder.singleton;

}

二:饿汉模式

原理:创建好一个静态变量,每次要用时直接返回。

缺点:无法做到延迟创建对象,在类加载时进行创建会导致初始化时间变长。

public classSingletonHungry {private static SingletonHungry instance = newSingletonHungry();privateSingletonHungry() {

}public staticSingletonHungry getInstance() {returninstance;

}

三:懒汉模式

原理:延迟创建,在第一次用时才创建,之后每次用到就返回创建好的。

缺点:由于synchronized的存在,多线程时效率很低。

public classSingletonLazy {private static volatileSingletonLazy instance;privateSingletonLazy() {

}public static synchronizedSingletonLazy getInstance() {if (instance == null) {

instance= newSingletonLazy();

}returninstance;

}

四:双重校验锁懒汉模式

原理:在getSingleton()方法中,进行两次null检查。这样可以极大提升并发度,进而提升性能。

public classSingleton {private static volatile Singleton singleton = null;//使用valatile,使该变量能被所有线程可见privateSingleton(){}public staticSingleton getSingleton(){if(singleton == null){synchronized (Singleton.class){//初始化时,加锁创建if(singleton == null){//为避免在加锁过程中被其他线程创建了,再作一次非空校验

singleton= newSingleton();

}

}

}returnsingleton;

}

五:上述4种方式实现单例模式的缺点

1、反序列化对象时会破环单例

反序列化对象时不会调用getXX()方法,于是绕过了确保单例的逻辑,直接生成了一个新的对象,破环了单例。

解决办法是:重写类的反序列化方法,在反序列化方法中返回单例而不是创建一个新的对象。

public class Singleton implementsjava.io.Serializable {public static Singleton INSTANCE = newSingleton();protectedSingleton() {

}//反序列时直接返回当前INSTANCE

privateObject readResolve() {returnINSTANCE;

}

}

2、在代码中通过反射机制,直接调用类的私有构造函数创建新的对象,会破环单例

解决办法是:维护一个volatile的标志变量在第一次创建实例时置为false;重写构造函数,根据标志变量决定是否允许创建。

private static volatile boolean flag = true;privateSingleton(){if(flag){

flag= false; //第一次创建时,改变标志

}else{throw new RuntimeException("The instance already exists !");

}

六:枚举模式实现单例——将单例维护在枚举类中作为唯一实例

原理:定义枚举类型,里面只维护一个实例,以此保证单例。每次取用时都从枚举中取,而不会取到其他实例。

public enumSingletonEnum {

INSTANCE;privateString name;publicString getName(){returnname;

}public voidsetName(String name){this.name =name;

}

优点:

1)使用SingletonEnum.INSTANCE进行访问,无需再定义getInstance方法和调用该方法。

2)JVM对枚举实例的唯一性,避免了上面提到的反序列化和反射机制破环单例的情况出现:每一个枚举类型和定义的枚举变量在JVM中都是唯一的。

原因:枚举类型在序列化时仅仅是将枚举对象的name属性输出到结果中,反序列化的时候则是通过java.lang.Enum的valueOf方法来根据名字查找枚举对象。

同时,编译器禁止重写枚举类型的writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。

java 内部类 单例_Java单例模式的几种实现相关推荐

  1. java socket 单例_Java 单例模式的几种实现方式

    单例模式的本质是在运行过程中,某个类只能实例化一个对象:下面是单例模式最基本的实现方式 package com.fuck.singleton; public class Singleton { pri ...

  2. java 窗口 单例_java单例模式实现面板切换

    本文实例为大家分享了java单例模式实现面板切换的具体代码,供大家参考,具体内容如下 1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public c ...

  3. java 工厂 单例_java 单例模式和工厂模式实例详解

    单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例. 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 饿汉式单例 public class ...

  4. java设计模式 单例_java设计模式一(单例模式singleton)

    1 概述 如果要保证系统里一个类最多只能存在一个实例时,我们就需要单例模式.这种情况在我们应用中经常碰到,例如缓存池.数据库连接池.线程池.一些应用服务实例等.在多线程环境中为了保证实例的唯一性其实并 ...

  5. java设计模式 单例_java设计模式--单例模式

    单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 核心知识点如下: (1) 将采用单例 ...

  6. java 内部类 单例_确保对象的唯一性——单例模式 (四):一种更好的单例实现方法(静态内部类)...

    3.5 一种更好的单例实现方法 饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存:懒汉式单例类线程安全控制烦琐,而且性能受影响.可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有 ...

  7. java connection 单例_Java设计模式之单例模式详解

    Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...

  8. java 变量单例_Java静态变量的用法:伪单例

    这几天遇到一个问题,一个Service里有一个map,但是这个Service有别的继承,于是每一个Service都会创建一个map,但是这个map应该是公用的,于是就有问题了...(按结构说Servi ...

  9. redis java api 单例_Java API 操作Redis

    针对Redis的Java客户端有很多种,具体查看官网信息:https://redis.io/clients#java 本次测试使用Jedis API,Jedis使用方便,其api方法名称与redis命 ...

最新文章

  1. java arraylist 序列化_无法序列化/反序列化ArrayList
  2. oracle 表连接 大表小表_优化必备基础:Oracle中常见的三种表连接方式
  3. 数据结构之——队列与循环队列
  4. 一个iOS表单框架-UFKit
  5. C#开发笔记之10-如何用C#根据发票代码判断发票种类?
  6. 超过1.2W星的「机器学习路线图」,你的收藏夹可以更新了!
  7. python-9:nonlocal,指定上一级变量
  8. I/O 多路复用的特点:
  9. 医脉神剑之超声成像基础原理(转)
  10. 电脑卡住了怎么保存excel_电脑卡死了excel没保存怎么办啊
  11. 即时通讯(WebSocket、Socket IO)
  12. 打造自己的MyLifeOrganized 2(MLO2)云同步
  13. 标题:缩位求和 在电子计算机普及以前,人们经常用一个粗略的方法来验算四则运算是否正确。 比如:248 * 15 = 3720 把乘数和被乘数分别逐位求和,如果是多位数再逐位求和,直到是1位数,得 2
  14. Python爬取m3u8格式视频并解密ts文件合并转为mp4格式
  15. 小世界效应:从凯文·贝肯到六度分隔理论(1)
  16. tableau-客户留存分析模型
  17. 使用Blob对象接收后台返回的图片流并展示到前端页面
  18. 华为交换机常见ARP操作
  19. fiddler对浏览器、app抓包及证书安装
  20. 记录学习npm私服的搭建与使用以及过程中的坑点

热门文章

  1. php验证微信公众号开发服务器token失败的原因之一
  2. 浅谈拉卡拉支付如何实现最佳用户体验的策略
  3. python语言中、用来表示赋值的符号是_第二章Python语言基础知识
  4. python炫酷烟花表白源代码-python实现浪漫的烟花秀
  5. d3-V5 力引导布局实例图
  6. webstorm浏览器图标出不来
  7. 程序员办公桌都是这么霸气的吗?扫码改需求?
  8. GAN、扩散模型应有尽有,CMU出品的生成模型专属搜索引擎Modelverse来了
  9. android 粘性弹窗,android组件化通信之EventBus粘性事件解析
  10. 禁止Chrome浏览器的“无法更新Chrome”弹窗