【Java】单例模式(Singleton)
重新搞一波 复习巩固
简单记录 慕课网 Java工程师
文章目录
单例概述
Singleton Pattern 单例模式是Java中最简单的设计模式之一, 属于创建类型的一种常用的软件设计模式,它提供了一种创建对象的最佳方式。
什么是单例?
单例,就是整个程序有且仅有一个实例。 该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,代表了最佳的实践, 通常被有经验的面向对象的软件开发人员所采用。
Christopher Alexander说过:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心,这样,你就能一次又一次地使用该方案而不必做重复劳动“。
使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。
设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案, 这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。
在项目中合理的运用设计模式可以完美的解决很多问题。
每种模式在现在中都有相应的原理与之对应。
每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案。
面向对象的设计模型很多,但大家认为这23个模式是其他模式的基础。
**创建型模式 (Creational Patterns) **
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
工厂模式 (Factory Pattern)
建造者模式 (Builder Pattern)
抽象工厂模式( Abstract Factory Pattern)
原型模式 (Prototype Pattern)
单例模式 (Singleton Pattern)
**结构型模式 (Structural Patterns) **
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 过滤器模式(Filter、Criteria Pattern)
- 组合模式(Composite Pattern)
- 装饰器模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
**解释器模式 (Behavioral Patterns) **
这些设计模式特别关注对象之间的通信。
- 责任链模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 解释器模式(Interpreter Pattern)
- 迭代器模式(Iterator Pattern)
- 中介者模式(Mediator Pattern)
- 备忘录模式(Memento Pattern)
- 观察者模式(Observer Pattern)
- 状态模式(State Pattern)
- 空对象模式(Null Object Pattern)
- 策略模式(Strategy Pattern)
- 模板模式(Template Pattern)
- 访问者模式(Visitor Pattern)
另一类设计模式:J2EE 设计模式。
这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。
- MVC 模式(MVC Pattern)
- 业务代表模式(Business Delegate Pattern)
- 组合实体模式(Composite Entity Pattern)
- 数据访问对象模式(Data Access Object Pattern)
- 前端控制器模式(Front Controller Pattern)
- 拦截过滤器模式(Intercepting Filter Pattern)
- 服务定位器模式(Service Locator Pattern)
- 传输对象模式(Transfer Object Pattern)
单例模式(Singleton)
滚滚历史,朝代更迭,永恒定律:
- 一个朝代皇帝只有一个
- 军队的最高司令官只有一个
- 一山不容二虎
计算机系统:
- 驱动程序
- 打印机后台处理程序(Printer Spooler)
- 线程池
- 缓存
- 日志
目的:
使得类的一个对象成为该类系统中的唯一实例
定义:
一个类有且仅有一个实例,并且自行实例化向整个系统提供
要点:
1、某个类只能有一个实例
2、必须自行创建实例
3、必须自行向整个系统提供这个实例
实现:
1、只提供私有的构造方法
2、含有一个该类的静态私有对象
3、提供一个静态的公有方法用于创建、获取静态私有对象
**主要解决:**一个全局使用的类频繁地创建与销毁。
**何时使用:**当您想控制实例数目,节省系统资源的时候。
**如何解决:**判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
**关键代码:**构造函数是私有的。
单例模式
代码实现方案:
1、饿汉式
2、懒汉式
饿汉式 PK 懒汉式
1、饿汉式在类加载时就创建实例,第一次加载速度快
懒汉式第一次使用时才进行实例化,第一个加载速度慢
饿汉式:空间换时间
懒汉式:时间换空间
2、饿汉式线程安全;懒汉式存在线程风险
解决方案:
1、同步锁
2、双重校验锁
双检锁/双重校验锁(DCL,即 double-checked locking)
**描述:**这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
getInstance() 的性能对应用程序很关键。
实例
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
单例模式
优点:
1、在内存中只有一个对象,节省内存空间
2、避免频繁的创建销毁对象,提高性能
3、避免对共享资源的多重占用
缺点:
1、扩展比较困难
2、如果实例化后的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态丢失
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
单例模式
适合场景:
1、创建对象时占用资源过多,但同时又需要用到该类对象
2、对系统内资源要求统一读写,如读写配置信息
3、当多个实例存在可能引起程序逻辑错误,如号码生成器
SingletonOne.java
package com.imooc.singleton;
//饿汉式:创建对象实例的时候直接初始化 空间换时间
public class SingletonOne {
//1、创建类中私有构造
private SingletonOne(){
}
//2、创建该类型的私有静态实例
private static SingletonOne instance=new SingletonOne();
//3、创建公有静态方法返回静态实例对象
public static SingletonOne getInstance(){
return instance;
}
}
SingletonTwo.java
package com.imooc.singleton;
//懒汉式:类内实例对象创建时并不直接初始化,直到第一次调用get方法时,才完成初始化操作
//时间换空间
public class SingletonTwo {
//1、创建私有构造方法
private SingletonTwo(){
}
//2、创建静态的该类实例对象
private static SingletonTwo instance=null;
//3、创建开放的静态方法提供实例对象
public static SingletonTwo getInstance(){
if(instance==null)
instance=new SingletonTwo();
return instance;
}
}
test.java
package com.imooc.test;
import com.imooc.singleton.SingletonOne;
import com.imooc.singleton.SingletonTwo;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
SingletonOne one =SingletonOne.getInstance();
SingletonOne two=SingletonOne.getInstance();
System.out.println(one);
System.out.println(two);
System.out.println("===================================");
SingletonTwo one1 =SingletonTwo.getInstance();
SingletonTwo two1=SingletonTwo.getInstance();
System.out.println(one1);
System.out.println(two1);
}
}
参考资料
[1]-慕课网 Java工程师就业班 - Java 零基础入门-Java面向对象-单例模式
[2]-菜鸟教程 - 单例模式
[3]-设计模式-作者: [[美] Erich Gamma](https://book.douban.com/search/Erich Gamma) / [Richard Helm](https://book.douban.com/search/Richard Helm) / [Ralph Johnson](https://book.douban.com/search/Ralph Johnson) / [John Vlissides](https://book.douban.com/search/John Vlissides)- Design Patterns: Elements of Reusable Object-Oriented Software
【Java】单例模式(Singleton)的更多相关文章
- Java单例模式(Singleton)以及实现
一. 什么是单例模式 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 二. 单例模式的特点 1. 单例模式只能有一个实例. 2. 单例类必须创建 ...
- java设计模式之 单例模式 Singleton
static 的应用 单例模式 Singleton 单例:保证一个类在系统中最多只创建一个实例. 好处:由于过多创建对象实例,会产生过多的系统垃圾,需要GC频繁回收,由于GC会占用较大的系统资源,所有 ...
- 创建模式--单例模式Singleton(JAVA)
创建模式之单例模式 在面试时经常会有人问单例模式,单例模式是在整个系统运行中仅且仅有一个实例,在被调用.我们熟知的Calendar就是这种, Calendar.newIns ...
- JAVA:将反射技术应用于工厂模式(Factory)和单例模式(Singleton)的简单代码
反射技术大量用于Java设计模式和框架技术,最常见的设计模式就是工厂模式(Factory)和单例模式(Singleton). 参考URL: http://blog.csdn.net/xiaohai79 ...
- JAVA设计模式-单例模式(Singleton)线程安全与效率
一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 【白话设计模式四】单例模式(Singleton)
转自:https://my.oschina.net/xianggao/blog/616385 0 系列目录 白话设计模式 工厂模式 单例模式 [白话设计模式一]简单工厂模式(Simple Factor ...
- ooad单例模式-Singleton
单例模式Singleton 主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 比如建立目录 ...
- 浅谈设计模式--单例模式(Singleton Pattern)
题外话:好久没写blog,做知识归纳整理了.本来设计模式就是个坑,各种文章也写烂了.不过,不是自己写的东西,缺少点知识的存在感.目前还没做到光看即能记住,得写.所以准备跳入设计模式这个大坑. 开篇先贡 ...
- 【深入】java 单例模式(转)
[深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便 ...
随机推荐
- vue+ springboot 分页(两种方式:sql分页 & PageHelper 分页)
方法一:sql分页 思路:使用数据库进行分页 前端使用element-ui的分页组件,往后台传第几页的起始行offest 以及每页多少行pageSize,后台根据起始行数和每页的行数可以算出该页的 ...
- 一文说通C#中的异步迭代器
今天来写写C#中的异步迭代器 - 机制.概念和一些好用的特性 迭代器的概念 迭代器的概念在C#中出现的比较早,很多人可能已经比较熟悉了. 通常迭代器会用在一些特定的场景中. 举个例子:有一个for ...
- js上 三、数据类型
3.1.什么是数据类型 a. 什么是数据类型? 想从生活中出发: 考验智商的时刻到了: 1(只)+1(只)=1(双) 3(天)+4(天)=1(周) 5(月)+7(月)=1(年) 4(时)+9(时)=1 ...
- Python编程基础:循环结构
一.为什么要用循环 现在有一个任务,要求你输出一百遍"好好学习,天天向上!",想一想,你会怎么做? (一)老老实实的笨方法 print("第1遍写:好好学习,天天向上!& ...
- Filezilla账号设置多个文件夹
问题描述 一个账号,使用多个文件目录.虽然可以这样设置,但是实际上客户端使用时只能使用一个目录(主目录). 所以想找一种方式,访问一个主目录时,也可以访问到其他的目录. 官网示例 https://wi ...
- Java学习_Java快速入门
Java简介 安装完JDK后,需要设置一个JAVA_HOME的环境变量,它指向JDK的安装目录.在Windows下,它是安装目录,类似: C:\Program Files\Java\jdk-15 把J ...
- 基于SpringBoot的博客项目
SpringBoot 博客系统 后端: 框架:SpringBoot 安全框架:shiro 数据库:mysql ORM:mybaits mybaits-plus 插件:lombok 模板引擎:thyme ...
- MySQL性能优化,MySQL索引优化,order by优化,explain优化
前言 今天我们来讲讲如何优化MySQL的性能,主要从索引方面优化.下期文章讲讲MySQL慢查询日志,我们是依据慢查询日志来判断哪条SQL语句有问题,然后在进行优化,敬请期待MySQL慢查询日志篇 建表 ...
- 详解CSS布局
CSS页面布局允许我们拾取网页中的元素,并且控制它们相对正常布局流.周边元素.父容器或者主视口/窗口的位置.主要对文档流的改变进行布局.假设你已经掌握了CSS的选择器.属性和值,并且可能对布局有一定了 ...
- 30天自制OS(linux环境)-day1
30天自制OS(linux环境)--第一天 我是在CentOS的环境上面实现的,使用ubuntu的环境也是类似的 第一步:因为要对二进制文件进行编辑,所以安装二进制编辑器hexedit(当然其他的也可 ...