Java实现单例模式的五种方法介绍
作者:Knight_AL 发布时间:2022-10-20 17:32:56
饿汉式
立即加载
防止new对象,构造私有,写一个公共的方法返回对象
占用空间,线程安全
public class Singleton {
/**
* 私有构造
*/
private Singleton(){
System.out.println("构造函数Singleton");
}
private static Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
}
懒汉式
延迟加载
占用空间小,效率有问题,线程不安全
public class Singleton {
/**
* 私有构造
*/
private Singleton(){
System.out.println("构造函数Singleton");
}
private static Singleton singleton = null;
public static Singleton getInstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
解决线程安全问题
在方法上加synchronized同步锁或是用同步代码块对类加同步锁,此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。
锁太大
public class Singleton {
/**
* 私有构造
*/
private Singleton(){
System.out.println("构造函数Singleton");
}
private static Singleton singleton = null;
public static synchronized Singleton getInstance(){
if (singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
双重检查锁
提高同步锁的效率
使用双重检查锁进一步做了优化,可以避免整个方法被锁,只对需要锁的代码部分加锁,可以提高执行效率。
第一个if判断
第一个线程进来new了Singleton,那么singleton就有值,第二个线程进来,那么进行第一个if判断,不为null,直接返回,不用再去new了,提升了效率
第二个if判断
两个线程同时进来,在synchronized,第一个线程进入,另一个线程等待,第一个线程new Singleton,然后返回,另一个线程发现了第一个线程走了,进入synchronized,如果不进行if判断,那么还会new Singleton,导致线程不安全
public class Singleton {
/**
* 私有构造
*/
private Singleton(){
System.out.println("构造函数Singleton");
}
private static Singleton singleton = null;
public static synchronized Singleton getInstance(){
if (singleton == null){ //这个检查是提高效率的
synchronized (Singleton.class){
if (singleton == null){
singleton = new Singleton(); //这个检查是防止线程安全的
}
}
}
return singleton;
}
}
静态内部类
这种方式引入了一个内部静态类(static class),静态内部类只有在调用时才会加载,它保证了Singleton 实例的延迟初始化,又保证了实例的唯一性。它把singleton 的实例化操作放到一个静态内部类中,在第一次调用getInstance() 方法时,JVM才会去加载InnerObject类,同时初始化singleton 实例,所以能让getInstance() 方法线程安全。
特点是:即能延迟加载,也能保证线程安全。
静态内部类虽然保证了单例在多线程并发下的线程安全性,但是在遇到序列化对象时,默认的方式运行得到的结果就是多例的。
public class Singleton {
/**
* 私有构造
*/
private Singleton(){
}
private static class InnerObject{
private static Singleton singleton = new Singleton();
}
public static synchronized Singleton getInstance(){
return InnerObject.singleton;
}
}
内部枚举类实现
防止反射和反序列化攻击
实上,通过Java反射机制是能够实例化构造方法为private的类的。这也就是我们现在需要引入的枚举单例模式。
public class SingletonFactory {
/**
* 私有构造
*/
private enum EnumSingleton{
SINGLETON;
private Singleton6 singleton;
//枚举类的构造方法在类加载是被实例化
private EnumSingleton(){
singleton = new Singleton6();
}
public Singleton6 getInstance(){
return singleton;
}
}
public static Singleton6 getInstance(){
return EnumSingleton.SINGLETON.getInstance();
}
}
class Singleton6{
public Singleton6(){
}
}
来源:https://donglin.blog.csdn.net/article/details/128773676
猜你喜欢
- 本文实例讲述了C#实现将Email地址转成图片显示的方法。分享给大家供大家参考。具体实现方法如下:private final static
- activity A和BA 获取数据的activity B返回数据的activity点击A上的按钮,在A的textview上显示
- 一、Java的前世为什么会产生Java?Java的特点是什么?从C语言开始讲,C语言是一种结构化语言,模块化编程,便于程序的调试,依靠非常全
- AOP概念的引入传统的登录原理:如上图所示这是一个基本的登录原理图,但是如果我们想要在这个登录之上添加一些新的功能,比如权限校验那么我们能想
- 在Java中可以使用HttpServer类来实现Http服务器,该类位于com.sun.net包下(rt.jar)。实现代码如下:主程序类p
- 1、SDK下载很慢。配置SDK代理,速度像飞一样。建议先把20-24下完,不然后面遇到很多问题。2、support-v7的问题例如res\v
- 基于SSM框架的仓库管理系统功能:系统操作权限管理。系统提供基本的登入登出功能,同时系统包含两个角色:系统超级管理员和普通管理员,超级管理员
- 本文实例讲述了java实现单词搜索迷宫游戏。分享给大家供大家参考。具体分析如下:我们在杂志上,经常能够看到找单词的小游戏,在一个二维表格中,
- 1.汉诺塔介绍汉诺塔规则1.有三根杆子A,B,C。A杆上有若干碟子2.每次移动一块碟子,小的只能叠在大的上面3.把所有碟子从A杆全部移到C杆
- 一般,我们的web应用都是只有在用户登录之后才允许操作的,也就是说我们不允许非登录认证的用户直接访问某些页面或功能菜单项。我还记得很久以前我
- Rmb.javapublic class Rmb { /** *人民币的基本信息和操作 *@auth
- 运用Java编写代码将一个大文件切割成指定大小的小文件思路:对已知文件进行切割操作 –> 得到多个碎片文件使用:1、 1个字节输入流
- java8 Stream大数据量List分批处理//按每3个一组分割private static final Integer MAX_NUM
- 一、作用:随机流(RandomAccessFile)不属于IO流,支持对文件的读取和写入随机访问。二、随机访问文件原理: 首先把随机访问的文
- 算法简介迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学迪家迪杰斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶
- 引言 在一些项目中或是一些特殊的业务场景中,需要用到显示系统的当前时间,以及一些
- thymeleaf介绍简单说, Thymeleaf 是一个跟 Velocity、FreeMarker 类似的模板引擎,它可以完全替代 JSP
- [LeetCode] 131.Palindrome Partitioning 拆分回文串Given a string s, par
- 原理解析:利用RandomAccessFile在本地创建一个随机访问文件,文件大小和服务器要下载的文件大小相同。 根据线程的数量(假设有三个
- 一、静态代理模式1.1、 代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标