③设计模式之单例模式
③单例模式
这个模式是很有趣而且也比较简单的,但是我还是要说,因为它是以是如此的广泛,如此的有人员,单例就是单一、独苗的意思,那什么是独一份呢?
我们举个比较难复制的对象:皇帝
中国历史上很少出现两个皇帝并存的时期,是有,但不多,那我们就认为皇帝是个单例模式,在这个场景中,有皇帝,有大臣,大臣是天天要商超参见皇帝的,今天参拜的皇帝应该和昨天的、前天的一样,大臣磕完头,抬头一看,还是昨天那个皇帝,单例模式,绝对的单例模式,现在看一下例图
然后我们看代码实现,先定一个皇帝:
package cn.cjm.singleCase;/*** 中国历史上一般都是一个朝代一个皇帝,有两个肯定要PK出来一个* <p>Title:Emperor </p>* <p>Description: </p>* @author cjm * @date 2017年9月1日 下午4:46:25*/public class Emperor {private static Emperor emperor = null;//定义一个皇帝放在那里,然后给这个皇帝名字private Emperor(){//为了不让你产生第二个皇帝,这里的构造方式设置为private}public static Emperor getInstance(){if(emperor == null){//如果皇帝还没定义,在这里new一个emperor = new Emperor();}return emperor;}// 皇帝叫什么名字public static void emperorInfo(){System.out.println("我就是皇帝"+emperor);}
}
定义大臣
package cn.cjm.singleCase;/*** 大臣是要天天见皇帝的,今天见的皇帝和昨天见的必须要相同* <p>Title:Minister</p>* <p>Description:</p>* @author cjm* @date 2017年9月1日 下午4:49:59*/public class Minister {public static void main(String[] args) {// 第一天Emperor emperor1 = Emperor.getInstance();emperor1.emperorInfo();// 第一天的皇帝叫什么名字呢?// 第二天Emperor emperor2 = Emperor.getInstance();emperor1.emperorInfo();// 第二天的皇帝叫什么名字呢?// 第三天Emperor emperor3 = Emperor.getInstance();emperor1.emperorInfo();// 第三天的皇帝叫什么名字呢?}}
看到没,大臣天天见到的都是同一个皇帝,不会产生错乱情况,反正都是一个皇帝,是好是坏都是一个,只要提到是皇帝,大家都知道指的是谁。问题是这是通常情况们还有个例,还有个例的,如图一个时期同一个朝代有两个皇帝,怎么办?
单例模式很简单,就是把构造方法的访问权限设置为private,这个模式是简单,但是简单中透着风险,什么风险?
在一个B/S项目中,每个HTTP Request 请求到J2EE的容器上后都创建了一个线程,每个线程都要创建同一个单例对象,怎么办?好,我们写一个通用的单例程序,然后分析一下:
/*** 通用单例模式* <p>Title:SingletonPattern </p>* <p>Description: </p>* @author cjm * @date 2017年9月1日 下午5:43:00*/public class SingletonPattern {private SingletonPattern singletonPattern = null;// 限制住不能直接产生一个实例private SingletonPattern(){ }public SingletonPattern getInstance(){if(this.singletonPattern == null){// 如果还没有实例,创建一个this.singletonPattern = new SingletonPattern();}return this.singletonPattern;}}
我们来看一下getInstance方法,加入现在有两个线程A和B,线程A执行到this.singletonPattern = new SingletonPattern(),正在申请内存分配,可能需要0.001微秒,就在这0.001微秒之内,线程B这行到if(this.singletonPattern == null),你说这个时候这个判断条件是true还是false?是true,那然后呢?线程B也往下走,于是乎就在内存中有了两个SingletonPattern的实例,看看是不是出问题了?
如果你这个单例是去拿一个序列号或者创建一个信号资源的时候,会怎么样?业务逻辑混乱!数据一致性校验失败!最重要的是你从代码上还看不出什么问题,这才是最要命的!因为这种情况基本上你是重现不了的,不寒而栗吧,那怎么修改?因为笔者水平有限,在这里提供一种最简单的方法
public class SingletonPattern {private static final SingletonPattern singletonPattern = new SingletonPattern();// 限制住不能直接产生一个实例private SingletonPattern(){}public SingletonPattern getInstance(){return this.singletonPattern;}}
直接new一个对象传递给类的成员变量SingletonPattern没你要的时候getInstance()直接返回给你,解决!
其实这就是懒汉式和饿汉式的区别,
饿汉式:类已加载就创建对象(例如Runtime)
懒汉式:用的时候,才去创建对象
可以看出,饿汉式是不会出问题的单例模式,懒汉式可能会出现问题的单例模式,因此要考虑线程安全问题。
线程安全问题
是否多线程环境 是
是否有共享数据 是
是否有多条语句操作共享数据 是
③设计模式之单例模式相关推荐
- socket可以写成单例嘛_精读《设计模式 - Singleton 单例模式》
Singleton(单例模式) Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一定范围内是唯一的. 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 其实单例模 ...
- C#设计模式(1)——单例模式
原文地址:http://www.cnblogs.com/zhili/p/SingletonPatterm.html 一.引言 最近在设计模式的一些内容,主要的参考书籍是<Head First 设 ...
- java设计模式之单例模式(七种方法)
单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...
- java单例模式的七种写法_Java设计模式之单例模式的七种写法
什么是单例模式? 单例模式是一种常见的设计模式,单例模式的写法有很多种,这里主要介绍三种: 懒汉式单例模式.饿汉式单例模式.登记式单例 . 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类 ...
- go设计模式之单例模式
在这里插入图片描述# go设计模式之单例模式 在软件开发时,经常会遇到有些对象需要保证只有一个实例的,那么这种设计模式就应用而生. 定义 单例模式,也叫单子模式,是一种常用的软件设计模式,属于创建型模 ...
- 一篇博客读懂设计模式之---单例模式
一篇博客读懂设计模式之---单例模式 一. 单例模式 单例对象(Singleton)是一种常用的设计模式.在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在.这样的模式有几个好处 ...
- Java 设计模式(3)单例模式
前言 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自 ...
- socket可以写成单例嘛_精读设计模式 Singleton 单例模式
Singleton(单例模式) Singleton(单例模式)属于创建型模式,提供一种对象获取方式,保证在一定范围内是唯一的. 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 其实单例模 ...
- 设计模式之单例模式——Singleton
设计模式之单例模式--Singleton 设计意图: 保证类仅有一个实例,并且可以供应用程序全局使用.为了保证这一点,就需要这个类自己创建自己的对象,并且对外有 ...
- 实践GoF的设计模式:单例模式
本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:单例模式>,作者: 元闰子. 简述 GoF 对单例模式(Singleton)的定义如下: Ensure a class onl ...
最新文章
- Keypress - 捕获键盘输入的JavaScript库
- [bzoj2527][Poi2011]Meteors_整体二分_树状数组
- 分割svm的超平面数学特征
- 将txt文件的编码格式进行修改
- linux nginx 重启_Nginx 的介绍及安装
- BinderHub 使用简介
- 嵌入式开发之davinci--- spi 中的时钟极性CPOL和相位CPHA
- SQL Server 2008 白皮书
- easyui tree复选框是否打钩状态_原创深度:如何利用OpenVINO工具套件监控机器操作员情绪状态(一)...
- 二维波动方程matlab,二维波动方程matlab
- 封校大学生无聊玩起图像大找茬——游戏脚本(一起领略Python脚本的风采吧)
- matlab方差 anov,MATLAB单因素方差分析
- window下ruby的下载与gem安装
- 基于S3c2440的多种显示屏测试方案
- 学习记录-FDD大规模MIMO系统的稀疏信道估计技术研究
- 解决win10系统alt+tab切换程序不显示程序缩略图问题
- Vue前端实战——外卖商家
- 视频教程-Prometheus+Grafana企业级监控实战(运维篇)2020年视频教程-Linux
- Real-Time Rendering Fourth Edition 学习笔记之 -- 第一章:介绍
- Java更好的字符串排序(字母顺序+数字大小排序)