前言 单例模式应该是设计模式中最容易理解也是用得最多的一种模式了,同时也是面试的时候最常被问到的模式。单例模式的作用就是确保在任何情况下都只有一个实例对象,并提供一个全局的访问点,理解起来并不难,但是要实现一个接近“完美”的单例模式却绝非易事。本文将介绍在Java中如何优雅地实现单例模式,并对比各种实现方式的优缺点,希望诸位在看完之后能对单例模式有更深入的理解。 一、单例模式的基础 单例模式的定义是确保某个类在任何情况下都只有一个实例,并且需要提供一个全局的访问点供调用者访问该实例的一种模式。要确保任何情况
在我前面有写过一篇关于单例模式的几种创建的文章,最近在看多线程的时候,发现如果使用双重检验锁则可能会发生问题,接下来看我细细道来
单例模式确保一个类只有一个实例,并提供一个全局访问点,实现单例模式的方法是私有化构造函数,通过getInstance()方法实例化对象,并返回这个实例
synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。
我们优化上面的代码,遇到并发,很容易想到加锁,把获取对象的方法加上关键字synchronized,很巧,这种写法也称为懒汉式单例 ,如下:
synchronized 关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。
单例模式用于Runtime,Calendar和其他的一些类中。“饿汉式”是在不管你用的用不上,一开始就建立这个单例对象
概念:单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
1 动机 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;一个系统只能有一个窗口管理器或文件系统;一个系统只能有一个计时工具或ID(序号)生成器。 如何保证一个类只有一个实例并且这个实例易于被访问呢?定义一个全局变量可以确保对象随时都可以被访问,但不能防止我们实例化多个对象。 一个更好的解决办法是让类自身负责保存它的唯一实例。这个类可以保证没有其他实例被创建,并且它可以提供一个访问该实例的方法。这就是单例模式的模式动机。 2 定义 单例模式确保
如何保证一个类只有一个实例,且该实例易于访问? 定义一个全局变量可以确保对象随时都可以被访问,但无法避免实例化多个对象。
单例模式有几种?饿汉式、懒汉式。这两种是最常见的。还有几种是对其扩展的。具体如下:
volatile 是 Java 的一个关键字,它提供了一种轻量级的同步机制。相比于重量级锁 synchronized,volatile 更为轻量级,因为它不会引起线程上下文的切换和调度。
所谓饿汉式单例设计模式,就是将类的静态实例作为该类的一个成员变量,也就是说在JVM 加载它的时候就已经创建了该类的实例,因此它不会存在多线程的安全问题。
单例模式是在面试中是最容易被考到的设计模式,这是因为单例模式是设计模式中最简单的,几行代码就能搞定(现场手写代码);同时单例模式又有多种实现方式,涉及到线程安全、懒加载、序列化等问题。
创建型:单例设计模式2目录介绍01.如何实现一个单例02.饿汉式实现方式03.懒汉式实现方式04.双重DCL校验模式05.静态内部类方式06.枚举方式单例07.容器实现单例模式01.如何实现一个单例介绍如何实现一个单例模式的文章已经有很多了,但为了保证内容的完整性,这里还是简单介绍一下几种经典实现方式。概括起来,要实现一个单例,我们需要关注的点无外乎下面几个:构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;考虑对象创建时的线程安全问题;考虑是否支持延迟加载;考虑 getI
双重检验锁单例模式实现了懒汉式单例模式的延迟加载和饿汉式单例模式的线程安全。其主要思路是在获取单例实例时,先检查是否已经实例化,如果没有才进行同步块。在同步块内部再进行一次实例化检查,以确保只有一个实例被创建。这样,就能够在保证单例实例唯一性的同时,减少了多线程环境下的性能开销。
在程序开发中我们往往会涉及到设计模式,那么什么是设计模式呢?官方正式的定义是一套被反复使用经过分类编目,且多数人知晓的代码设计经验总结。简单的说设计模式是软件开发人员在软件开发过程中面临问题时所做出的解决方案。常用的设计模式有23中,因为篇幅有限在本篇文章中我之讲解23中设计模式中最经典的模式:单例模式。
Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide
博客:https://www.jianshu.com/u/0438038fe17e
前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式。 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个。 单例模式 单例模式的实现方式 实现单例模式的方式有很多种,大体上可以划分为如下两种。 外部方式 在使用某些全局对象时,做一些“try-Use”的工作。就是如果要使用的这个全局对象不存在,就自己创建一个,把它放到全局的位置上;如果本来就有,则直接拿来使用。 内部实现方式 类型自己控制正常实例的数量,无论客户程序是否尝试过
单例模式 一、特点: 二.分类 (一)、懒汉式单例 (二)、双重检查锁定 (三)、静态(类级)内部类 (四)、饿汉式单例 (五)、单例和枚举 三、饿汉式和懒汉式区别 一、特点: 1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。 单例模式确
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/156983.html原文链接:https://javaforall.cn
在懒加载模式中,每次获取实例都要加锁,这会使程序运行速度变慢,通过双重判断加锁机制可以解决这个问题
1、单例类只能有一个实例。 2、单例类必须自己创建自己的唯一实例。 3、单例类必须给所有其他对象提供这一实例。
单例模式在网上已经是被写烂的一种设计模式了,笔者也看了不少的有关单例模式的文章,但是在实际生产中使用的并不是很多,如果一个知识点,你看过100遍,但是一次也没实践过,那么它终究不是属于你的。因此我借助这篇文章来复习下设计模式中的单例模式。
前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 本来打算没那么快更新的,这阵子在刷Spring的书籍。在看Spring的时候又经常会看到“单例”,“工厂”这些字样。 所以,就先来说说单例和工厂设计模式啦,这两种模式也是很常见的,我看很多面经都会遇到这两种模式~ 本文主要讲解单例设计模式,如果有错的地方希望能多多包涵,并不吝在评论区指正! 一、单例模式概述 单例模式定义很简单:一个类中能创建一个实例,所以称之为单例! 那我们什么时候会用到单例模式呢?? 那我们想想
概述:本文主要介绍Java语言中的volatile关键字,内容涵盖volatile的保证内存可见性、禁止指令重排等。
对于从事java开发工作的朋友来说,在工作中可能会经常接触volatile关键字。即使有些朋友没有直接使用volatile关键字,但是如果使用过:ConcurrentHashMap、AtomicInteger、FutureTask、ThreadPoolExecutor等功能,它们的底层都使用了volatile关键字,你就不想了解一下它们为什么要使用volatile关键字,它的底层原理是什么?
关键代码:构造函数是私有的。 应用场景: 1.一些设备管理器常常设计为单例模式,比如一个电脑有两台打印机,在输出的时候就要处理不能两台打印机打印同一个文件。 2.创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。 3.Web应用的配置对象的读取,一般也应用单例模式,这个是由于配置文件是共享的资源。 UML图:
在程序设计中,有些对象通常只需要一个共享的实例,比如线程池、全局缓存、对象池等。实现共享实例最简单直接的方式就是全局变量。但是,使用全局变量会带来一些问题,比如:
在线程中的run方法上不能使用throws来声明抛出异常,所以在run方法中调用有可能出现异常的代码时,只能使用try-catch将其捕获来处理。
前言 只有光头才能变强 回顾前面: 给女朋友讲解什么是代理模式 包装模式就是这么简单啦 本来打算没那么快更新的,这阵子在刷Spring的书籍。在看Spring的时候又经常会看到“单例”,“工厂”这些字样。 所以,就先来说说单例和工厂设计模式啦,这两种模式也是很常见的,我看很多面经都会遇到这两种模式~ 本文主要讲解单例设计模式,如果有错的地方希望能多多包涵,并不吝在评论区指正! 一、单例模式概述 单例模式定义很简单:一个类中能创建一个实例,所以称之为单例! 那我们什么时候会用到单例模式呢?? 那我们想想既然一
在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致性的结果。
懒汉 /** * 懒汉,线程不安全 * 由私有构造器和一个公有静态工厂方法构成,在工厂方法中对singleton进行null判断,如果是null就new一个出来,最后返回singleton对象 * 这种方法可以实现延时加载(lazy landing),但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。 * Created by gongzi on 2017/2/13. */ public class LazySingleton
这是设计模式的第一篇文章,我们从单例模式开始入手,单例模式是 Java 设计模式中最简单的一种,只需要一个类就能实现单例模式,但是,你可不能小看单例模式,虽然从设计上来说它比较简单,但是在实现当中你会遇到非常多的坑,所以,系好安全带,上车。
私有构造函数保证了不能通过构造函数来创建对象实例,只能通过公有静态函数返回唯一的私有静态变量。
单例可以说是最简单的一个设计模式了,单例模式要求只能创建一个对象实例。通常的写法是声明私有的构造函数,提供静态方法获取单例的对象实例。
线程不安全的问题分析:在小朋友抢气球的案例中模拟网络延迟来将问题暴露出来;示例代码如下:
1.前言 写完这个题目,我感觉自己好像”孔乙己”啊,回字的四种写法要不要学啊~ 我们经常会用到单例模式,但是我对他一直没有一个统一的的认识,比如我清楚好多种单例的写法,但是每一种是怎么演化来的?具体解
所以我们在设计多线程代码的时候就必须在满足线程安全的前提下尽可能的提高任务执行的效 故: 加锁细粒度化:加锁的代码少一点,让其他代码可以并发并行的执行
因为instance是个静态变量,所以它会在类加载的时候完成实例化,不存在线程安全的问题。
上面代码中,通过关键字synchronized声明公共的获取实例的方法getInstance(),可以确保线程安全,能做到延迟加载,但是效率不高。
单例模式是我们最熟悉不过的一种设计模式,用来保证内存中只有一个对象的实例。虽然容易,但里面的坑也有很多,比如双重检验锁模式(double checked locking pattern)真的是线程安全的吗?
以下实现中,私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null) ,并且此时 uniqueInstance 为 null,那么会有多个线程执行 uniqueInstance = new Singleton(); 语句,这将导致多次实例化 uniqueInstance。
从本篇文章开始,我们就进入到了单例模式,关于单例模式里的分支模式会在后续的文章中一一讲解
领取专属 10元无门槛券
手把手带您无忧上云