手写单例,不心慌 原创 secondriver 2018-08-25 16:04:42 博主文章分类:日常札记 ©著作权 文章标签 单例 设计模式 懒汉式 饿汉式 文章分类 Java 后端开发 ©著作权归作者所有:来自51CTO博客作者secondriver的原创作品,请联系作者获取转载授权,否则将追究法律责任 手写单例,不心慌 单例模式是最常用到的设计模式之一,熟悉设计模式的朋友对单例模式都不会陌生。一般介绍单例模式的书籍,文章都会提到 饿汉式 和 懒汉式 这两种实现方式。但是除了这两种方式,实际上还有很多中方式。 模式简介 单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。 许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。 实现思路 单例模式要求类能够有返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是可见的静态方法,通常使用getInstance这个名称)。 单例的实现主要是通过以下两个步骤: 将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例; 在该类内提供一个可见的静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。 注意事项 单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。 单例模式的八种写法 1、饿汉式(静态常量)[可用] //单例饿汉式实现 public class Singleton { private final static Singleton INSTANCE = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return INSTANCE; } } //测试方法 public static void main(String [] args){ //输出:true 单例正确,否则错误 System.out.println(Singleton.getInstance()==Singleton.getInstance()); } **优点:**这种写法比较简单,就是在类装载的时候就完成实例化,避免了线程同步问题。 **缺点:**在类装载的时候就完成实例化,没有达到Lazy Loading的效果。如果从始至终从未使用过这个实例,则会造成内存的浪费。 2、饿汉式(静态代码块)[可用] public class Singleton { private static Singleton instance; static { instance = new Singleton(); } private Singleton() {} public Singleton getInstance() { return instance; } } 这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,就执行静态代码块中的代码,初始化类的实例。 优缺点和上面是一样的。 3、懒汉式(线程不安全)[不可用] public class Singleton { private static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } } 这种写法起到了Lazy Loading的效果,但是只能在单线程下使用。如果在多线程下,一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以在多线程环境下不可使用这种方式。 4、懒汉式(线程安全,同步方法)[不推荐用] public class Singleton { private static Singleton singleton; private Singleton() {} public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } } 解决上面第三种实现方式的线程不安全问题,做个线程同步就可以了,于是就对getInstance()方法进行了线程同步。 **缺点:**效率太低了,每个线程在想获得类的实例时候,执行getInstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低要改进。 5、懒汉式(线程安全,同步代码块)[不可用] public class Singleton { private static Singleton singleton; private Singleton() {} public static Singleton getInstance() { if (singleton == null) { synchronized (Singleton.class) { singleton = new Singleton(); } } return singleton; } } 由于第四种实现方式同步效率太低,所以摒弃同步方法,改为同步产生实例化的的代码块。但是这种同步并不能起到线程同步的作用。跟第3种实现方式遇到的情形一致,假如一个线程进入了if (singleton == null)判断语句块,还未来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。 6、懒汉式(双重检查)[推荐用] public class Singleton { private static volatile Singleton singleton; private Singleton() {} public static Singleton getInstance() { //双重检查 if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } } Double-Check概念对于多线程开发者来说不会陌生,如代码中所示,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。这样,实例化代码只用执行一次,后面再次访问时,判断if (singleton == null),直接return实例化对象。 **优点:**线程安全;延迟加载;效率较高。 7、静态内部类[推荐用] public class Singleton { private Singleton() {} private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonInstance.INSTANCE; } } 这种方式跟饿汉式方式采用的机制类似,但又有不同。两者都是采用了类装载的机制来保证初始化实例时只有一个线程。不同的地方在饿汉式方式是只要Singleton类被装载就会实例化,没有Lazy-Loading的作用,而静态内部类方式在Singleton类被装载时并不会立即实例化,而是在需要实例化时,调用getInstance方法,才会装载SingletonInstance类,从而完成Singleton的实例化。 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM帮助我们保证了线程的安全性,在类进行初始化时,别的线程是无法进入的。 **优点:**避免了线程不安全,延迟加载,效率高。 8、枚举[推荐用] public enum Singleton { INSTANCE; public void method() { } } 借助JDK1.5中添加的枚举来实现单例模式。不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象, 防止通过反射进行单例***。可能是因为枚举在JDK1.5中才添加,所以在实际项目开发中,很少见人这么写过。 单例优点 系统内存中该类只存在一个对象,节省了系统资源,对于一些需要频繁创建销毁的对象,使用单例模式可以提高系统性能。 单例缺点 当想实例化一个单例类的时候,必须要记住使用相应的获取对象的方法,而不是使用new,可能会给其它开发人员造成困扰,特别是看不到源码的时候。 适用场合 需要频繁的进行创建和销毁的对象; 创建对象时耗时过多或耗费资源过多,但又经常用到的对象; 工具类对象; 频繁访问数据库或文件的对象。 赞 收藏 评论 分享 举报 上一篇:CentOS 6.5下编译安装MySQL 5.6.14 下一篇:Java小应用目录快速变网站 提问和评论都可以,用心的回复会被更多人看到 评论 发布评论 全部评论 () 最热 最新 相关文章 为什么在开发中,不推荐用单例模式 在软件开发中,单例模式并不总是被推荐使用,主要有以下几个原因:全局状态:单例模式会引入全局状态,这可能导致系统的不可预测性增加。全局状态使得代码难以测试和调试,因为它增加了代码之间的耦合度。隐藏依赖关系:使用单例模式时,类的依赖关系通常会被隐藏起来。这意味着类的调用者可能不清楚其依赖的实例是一个单例,从而增加了代码的不透明性和复杂性。并发风险:如果单例模式未经适当设计,在多线程环境下可能会引发并发 单例模式 依赖关系 单例类 【设计模式】单例模式——单例模式的常见实现方式 单例模式饿汉式单例模式的最简单实现如下:public class Singleton implements Serializable { private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return i 饿汉式 线程安全 java 设计模式--单例模式 设计模式是软件工程中共同的问题的解决方案,这些方案经过了验证和总结,能够在不同的情境中提供最佳的解决途径。设计模式主要分为三类:创建型模式、结构型模式和行为型模式。以下是这三类模式中的 23 个经典设计模式的列表:创建型模式(Creational Patterns):创建型模式涉及对象的初始化和创建过程,它可以使得系统在不需要指定精确类的情况下创建对象。单例(Singleton)原型(Protot 初始化 线程安全 设计模式 java 手写单例 # Java手写单例教程## 1. 简介在Java中,单例模式是一种常见的设计模式,用于确保类只能有一个实例,并提供一个全局访问点。它常用于控制资源访问、限制对象数量等场景。本教程将教会你如何手写一个Java单例。## 2. 实现步骤下面是实现Java单例的步骤:| 步骤 | 描述 ||---|---|| 1 | 创建一个私有静态成员变量来保存单例实例 || 2 | 将构造 构造方法 Java 实例化 【iOS开发】手写单例 转载地址:单例1、单例用途限制创建,提供全局调用,节约资源和提高性能 static的作用:防止外部访问 @synchronized的作用 类名 内存空间 多线程 python 手写单例模式 1. 单例模式代码代码# 单例模式class SingleTon: def __new__(cls, *args, **kwargs): i 单例模式 单列模式 字节 面试 手写单例模式 手写单例模式静态内部类方式 懒汉加载加载一个类时,其内部类不会同时被加载。一个类被加载,当且仅当其某个静态成员(静态域、构造器、静态方法等)被调用时发生。由于在调用 StaticSingleton.getInstance() 的时候,才会对单例进行初始化,而且通过反射,是不能从外部类获取内部类的属性的;由于静态内部类的特性,只有在其被第一次引用的时候才会被加载,所以可以保证其线程安全 面试复习 面试之---手写单例模式 -------------在面试中,可能会遇到让直接写一个单例模式,不会在意你会不会,理解不理解这东西,只要能写出来,面试就还能进行下去//饿汉式class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } static Sin... 面试 心慌 是不是很羡慕那种,每天上班无所事事,坐等下班的同事 ? 二维码 微信 第三方平台 java手写一个单例 # Java单例模式详解单例模式是一种常见的设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在Java中,实现单例模式有多种方式,本文将介绍其中最常用的几种方式。## 1. 懒汉式(Lazy Initialization)懒汉式是最简单的一种单例实现方式,它在第一次使用时才创建实例。通常懒汉式需要考虑线程安全性,下面是一个使用双重检查锁定实现的懒汉式单例代码示例:```j 类加载 单例模式 线程安全 剑指offer(0)--手写单例模式 剑指Offer的第0题:如何手写一个单例模式的代码?文章目录1.单例模式是什么?2.为什么要用单例模式?3.单例模式有什么优缺点?4.单例模式有哪些用法? 剑指Offer 手写单例模式java 枚举 手写单例设计模式 单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。正是因为简单,也成为面试中的众矢之的。本文来手写单例模式。 单例模式是一种常用的设计模式,该模式提供了一种创建对象的方法,确保在程序中一个类最多只有一个实例。单例有什么用处?有一些对象其实我们只需要一个,比如线程池、缓存、对话框、处理偏好设置和注册表的对象、日志对 手写单例模式java 枚举 单例模式 实例化 静态变量 springboot手写单例模式 springboot 单例 在日常项目开发中,单例模式可以说是最常用到的设计模式,项目也常常在单例模式中需要使用 Service 逻辑层的方法来实现某些功能。通常可能会使用 @Resource 或者 @Autowired 来自动注入实例,然而这种方法在单例模式中却会出现 NullPointException 的问题。那么本篇就此问题做一下研究。问题初探一般我们的项目是分层开发的,最经典的可能就是下面这种结构:├── User springboot手写单例模式 java spring 获取数据 实例化 java手写单例 java手写arraylist List集合是我们平时常用的集合框架,List集合是有序的,在java中List接口主要有两个实现分别是ArrayList和LinkedList,其中ArrayList类主要是通过数组的方式实现的。因为ArrayList底层是通过数组的方式实现List集合,所以在访问集合中的数据时可以直接通过数组的下标访问,效率较高。由于在java中数组的大小必须在定义数组时确定并且不 java手写单例 ide ci List java手写单例模式 1 懒汉模式 public class Singleton { private Singleton singleton = null; private Singleton() { } public Singleton getInstance() { if (singleton == null) { java 线程安全 懒汉模式 饿汉模式 内部类 Java 手写ArrayList java 手写单例模式 单例模式是一种常用的设计模式,该模式提供了一种创建对象的方法,确保在程序中一个类最多只有一个实例。单例有什么用处?有一些对象其实我们只需要一个,比如线程池、缓存、对话框、处理偏好设置和注册表的对象、日志对象,充当打印机、显示等设备的驱动程序对象。其实,这类对象只能有一个实例,如果制造出来多个实例,就会导致许多问题,如:程序的行为异常、资源使用过量,或者是不一致的结果。Singleton通常用来代表 Java 手写ArrayList 设计模式 java 单例模式 实例化 ios的单例的正确写法 单例模式 手写 1懒汉式1.1懒汉式,线程不安全这段代码简单明了,而且使用了懒加载模式,但是却存在致命的问题。当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作public class Singleton{ private static Singleton instance; private Singleton(){} public static Si ios的单例的正确写法 线程安全 重排序 Java java 手写 生产模式 java手写单例模式 单例模式算是设计模式中最容易理解,也是最容易手写代码的模式了吧。但是其中的坑却不少,所以也常作为面试题来考。本文主要对几种单例写法的整理,并分析其优缺点。很多都是一些老生常谈的问题,但如果你不知道如何创建一个线程安全的单例,不知道什么是双检锁,那这篇文章可能会帮助到你。懒汉式,线程不安全当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样教我们的。public cl java 手写 生产模式 线程安全 重排序 Java java 单例不释放 java的单例 概念:java中单例模式是一种常见的设计模式,单例模式分三种:懒汉式单例、饿汉式单例、登记式单例三种。单例模式有一下特点:1、单例类只能有一个实例。2、单例类必须自己自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应 java 单例不释放 java单列模式详解 单例类 System 实例化 Java中手写单例模式 java手写分页功能 虽然现在有很多好用的框架,对分页进行支持,很简单的就把分页的效果做出来,但是如果自己手写是一个怎样的流程的?今天就来说说它,手动实现分页效果。 --WH 一、分页的思路 首先我们得知道写分页代码时的思路,保持思路清晰,有步骤的进行,才能行云如水。先来看看分页的效果 Java中手写单例模式 分页 数据 超链接