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

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

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

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. Nacos源码系列——第二章(Nacos核心源码主线剖析下)
  2. 在spring中,prototype scoped bean 如何注入单例bean中
  3. linux的简单面试题,收集的一些简单的UNIX/Linux面试题
  4. MySQL 索引的问题
  5. 如何使用 ABAP 报表将 ABAP 服务器上的 SAP UI5 应用下载到本地
  6. Codeforces Round #632 (Div. 2) F. Kate and imperfection 数论 + 贪心
  7. 关于CEdit控件的透明
  8. python 目录 文件名_python目录与文件名操作
  9. 存储过程、游标和触发器
  10. pyjion python3.6_[新闻] CPython / 微软 Pyjion / IBM Python+OMR
  11. C#winform省市县联动,以及有的县是空值时显示异常的处理
  12. 这套神奇的个人信息管理系统,带我一步步进入互联网大厂
  13. struts2 + spring + mybatis 框架整合
  14. size ar objdump readelf binutils
  15. android消息提示框大小,android Toast設置彈框大小
  16. java小球下落_java基础-小球下落问题
  17. uni-app初学步骤教程:
  18. SMT贴片加工防静电基础知识
  19. 蓝桥杯: 调手表【BFS】【Python】
  20. ipscan怎么用?ipscan使用方法

热门文章

  1. MQ消息队列使用场景
  2. 剑与轮回服务器维护,剑与轮回8月29日例行维护公告_剑与轮回8月29日更新了什么_玩游戏网...
  3. 友盟+尚直虎:大数据重塑数字营销方式
  4. winform C# 可取消的超时任务(时间精度高)
  5. 真香!IDEA 最新版本,支持免打扰模式!
  6. 关于webstrom右上角浏览器图标没显示问题
  7. 前端配置反向代理proxyTable
  8. 编程中大量数据的优化技巧
  9. 利用谷歌语法进行漏洞搜索
  10. OOP基础 、 OOP进阶 、 re模块案例