java 内部类 单例_Java单例模式的几种实现
一:静态内部类实现单例模式
原理:通过一个静态内部类定义一个静态变量来持有当前类实例,在类加载时就创建好,在使用时获取。
缺点:无法做到延迟创建对象,在类加载时进行创建会导致初始化时间变长。
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单例模式的几种实现相关推荐
- java socket 单例_Java 单例模式的几种实现方式
单例模式的本质是在运行过程中,某个类只能实例化一个对象:下面是单例模式最基本的实现方式 package com.fuck.singleton; public class Singleton { pri ...
- java 窗口 单例_java单例模式实现面板切换
本文实例为大家分享了java单例模式实现面板切换的具体代码,供大家参考,具体内容如下 1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public c ...
- java 工厂 单例_java 单例模式和工厂模式实例详解
单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例. 私有的构造方法 指向自己实例的私有静态引用 以自己实例为返回值的静态的公有的方法 饿汉式单例 public class ...
- java设计模式 单例_java设计模式一(单例模式singleton)
1 概述 如果要保证系统里一个类最多只能存在一个实例时,我们就需要单例模式.这种情况在我们应用中经常碰到,例如缓存池.数据库连接池.线程池.一些应用服务实例等.在多线程环境中为了保证实例的唯一性其实并 ...
- java设计模式 单例_java设计模式--单例模式
单例设计模式 Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点. 核心知识点如下: (1) 将采用单例 ...
- java 内部类 单例_确保对象的唯一性——单例模式 (四):一种更好的单例实现方法(静态内部类)...
3.5 一种更好的单例实现方法 饿汉式单例类不能实现延迟加载,不管将来用不用始终占据内存:懒汉式单例类线程安全控制烦琐,而且性能受影响.可见,无论是饿汉式单例还是懒汉式单例都存在这样那样的问题,有没有 ...
- java connection 单例_Java设计模式之单例模式详解
Java设计模式之单例模式详解 什么是设计模式 设计模式是在大量的实践中总结和理论之后优选的代码结构,编程风格,以及解决问题的思考方式.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可 ...
- java 变量单例_Java静态变量的用法:伪单例
这几天遇到一个问题,一个Service里有一个map,但是这个Service有别的继承,于是每一个Service都会创建一个map,但是这个map应该是公用的,于是就有问题了...(按结构说Servi ...
- redis java api 单例_Java API 操作Redis
针对Redis的Java客户端有很多种,具体查看官网信息:https://redis.io/clients#java 本次测试使用Jedis API,Jedis使用方便,其api方法名称与redis命 ...
最新文章
- Nacos源码系列——第二章(Nacos核心源码主线剖析下)
- 在spring中,prototype scoped bean 如何注入单例bean中
- linux的简单面试题,收集的一些简单的UNIX/Linux面试题
- MySQL 索引的问题
- 如何使用 ABAP 报表将 ABAP 服务器上的 SAP UI5 应用下载到本地
- Codeforces Round #632 (Div. 2) F. Kate and imperfection 数论 + 贪心
- 关于CEdit控件的透明
- python 目录 文件名_python目录与文件名操作
- 存储过程、游标和触发器
- pyjion python3.6_[新闻] CPython / 微软 Pyjion / IBM Python+OMR
- C#winform省市县联动,以及有的县是空值时显示异常的处理
- 这套神奇的个人信息管理系统,带我一步步进入互联网大厂
- struts2 + spring + mybatis 框架整合
- size ar objdump readelf binutils
- android消息提示框大小,android Toast設置彈框大小
- java小球下落_java基础-小球下落问题
- uni-app初学步骤教程:
- SMT贴片加工防静电基础知识
- 蓝桥杯: 调手表【BFS】【Python】
- ipscan怎么用?ipscan使用方法