Java 设计模式之单例模式(一)
原文地址:Java 设计模式之单例模式(一)
博客地址:http://www.extlight.com

一、背景
没有太多原由,纯粹是记录和总结自己从业以来经历和学习的点点滴滴。
本篇内容为 Java 设计模式系列的第一篇。
二、简单介绍
2.1 定义
单例模式是一种对象创建型模式,保证一个类只有一个实例,并且提供能对该实例加以访问的全局方法。
2.2 应用场景
操作系统的任务管理器
读取配置文件的类
数据库连接池
Javaweb 中的 Servlet 实例
Spring 创建的实例,默认为单例
...
三、实现方式
常用的实现方式有饿汉式、懒汉式和枚举类。
本篇文章主要讲饿汉式和懒汉式的单例模式。
共同点:将构造方法私有化,并且提供一个公共的方法访问该类的实例对象。
我们以任务管理器为例进行演示。
3.1 饿汉式
public class TaskManager {
private static TaskManager tm = new TaskManager();
private TaskManager() {
}
public static TaskManager getInstance() {
return tm;
}
}
优点:线程安全,不用加同步锁,因此在高并发时调用效率高。
缺点:不能懒加载,如果不使用该类的实例,浪费内存资源。
3.2 懒汉式
public class TaskManager {
private static TaskManager tm;
private TaskManager() {
}
public static synchronized TaskManager getInstance() {
if (tm == null) {
tm = new TaskManager();
}
return tm;
}
}
优点:实现懒加载,合理利用系统资源。
缺点:需要添加同步锁,高并发时调用效率不高。
注意点:上边的懒汉式可以通过反射机制创建多个实例。
public class Client {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("com.light.gof.singleton.TaskManager");
Constructor<?> constructor = clazz.getDeclaredConstructor(null);
// 跳过检测机制
constructor.setAccessible(true);
TaskManager tm1 = (TaskManager) constructor.newInstance();
TaskManager tm2 = (TaskManager) constructor.newInstance();
System.out.println(tm1 == tm2);// 结果返回 false
}
}
3.3 优化方式
将饿汉式和懒汉式的优点集中起来。
public class TaskManager {
private TaskManager() {
}
private static class InnerTaskManager {
private static final TaskManager tm = new TaskManager();
}
public static TaskManager getInstance() {
return InnerTaskManager.tm;
}
}
外部类没有静态属性,因此不会像饿汉式立即加载对象。
只有当调用公共方法(getInstance)时,才会加载静态内部类。加载内部类的过程是线程安全的。
内部类中通过 static final 确保内存中只有一个外部类的实例,因为实例变量(tm)只能被赋值一次。
四、UML 类图
类图表现如下:

五、性能比较
public class Client {
public static void main(String[] args) throws Exception {
// 线程数
int num = 10;
// 计数器
CountDownLatch cd = new CountDownLatch(num);
long t1 = System.currentTimeMillis();
for (int i = 0; i < num; i++) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
// 此处替换不同实现方式的单例代码进行测试
TaskManager tm = TaskManager.getInstance();
}
cd.countDown();
}
}).start();
}
// 主线程等待
cd.await();
System.out.println("耗时:" + (System.currentTimeMillis() - t1) + "ms");
}
}
测试结果:
| 实现方式 | 耗时 |
|---|---|
| 饿汉式 | 3ms |
| 懒汉式 | 12ms |
| 内部类方式 | 4ms |
测试结果是相对的,硬件配置不同,测试结果不同,但是对于这个 3 种实现方式,它们的用时比例应该大致相同。
Java 设计模式之单例模式(一)的更多相关文章
- java 设计模式之单例模式
-------Success is getting what you want, happiness is wanting what you get. java设计模式之单例模式(Singleton) ...
- 折腾Java设计模式之单例模式
博文原址:折腾Java设计模式之单例模式 单例模式 Ensure a class has only one instance, and provide a global point of access ...
- Java设计模式之单例模式(七种写法)
Java设计模式之单例模式(七种写法) 第一种,懒汉式,lazy初始化,线程不安全,多线程中无法工作: public class Singleton { private static Singleto ...
- java设计模式1——单例模式
java设计模式1--单例模式 1.单例模式介绍 1.1.核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 1.2.常见场景 1.3.单例模式的优点 1.4.常见的五种单例模式实现 ...
- java设计模式之单例模式你真的会了吗?(懒汉式篇)
java设计模式之单例模式你真的会了吗?(懒汉式篇) 一.什么是单例模式? 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供 ...
- java设计模式之单例模式(几种写法及比较)
概念: Java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例.饿汉式单例.登记式单例. 单例模式有以下特点: 1.单例类只能有一个实例. 2.单例类必须自己创建 ...
- java设计模式- (1)单例模式
参加校园招聘的笔试,发现公司都会考一些java设计模式,所以上网查询相关内容,总结常用的几种单例模式. 单例模式(Singleton Pattern)是 Java中最简单的设计模式之一.这种类型的设计 ...
- [转]JAVA设计模式之单例模式
原文地址:http://blog.csdn.net/jason0539/article/details/23297037 概念: java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主 ...
- java设计模式之单例模式(七种方法)
单例模式:个人认为这个是最简单的一种设计模式,而且也是在我们开发中最常用的一个设计模式. 单例模式的意思就是只有一个实例.单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.这个 ...
随机推荐
- 已经安装了node和npm,输入node -v 未找到命令
昨天虚拟机上安装了nvm.node.npm,今天打开输入node -v,就显示未找到命令 输入nvm --version 发现还是有nvm版本的,不然都要以为刚配好的虚拟机又要重新安装... 再输入 ...
- UVALive-5135 Mining Your Own Business (无向图的双连通分量)
题目分析:在一张无向图中,将一些点涂上黑色,使得删掉图中任何一个点时,每个连通分量至少有一个黑点.问最少能涂几个黑点,并且在涂最少的情况下有几种方案. 题目分析:显然,一定不能涂割点.对于每一个连通分 ...
- Linux命令nohup+screen 转
如果想在关闭ssh连接后刚才启动的程序继续运行怎么办,可以使用nohup.但是如果要求第二天来的时候,一开ssh,还能查看到昨天运行的程序的状态,然后继续工作,这时nohup是不行了,需要使用scre ...
- 034——VUE中表单控件处理之使用vue控制radio表单的实例操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- CMDB开发(需求分析)
浅谈ITIL TIL即IT基础架构库(Information Technology Infrastructure Library, ITIL,信息技术基础架构库)由英国政府部门CCTA(Central ...
- 在IE中MVC控制器中返回JSON格式的数据时提示下载
最近做项目时,视图中用jquery.form.js异步提交表单时,接收的是JSON格式的数据,但是奇怪的是在IE中提示下载文件,其他浏览器中一切正常,下载后,里面的内容就是在控制器中返回的数据.代码如 ...
- Deepgreen DB简介(转)
原文链接 Deepgreen DB 全称 Vitesse Deepgreen DB,它是一个可扩展的大规模并行(通常称为MPP)数据仓库解决方案,起源于开源数据仓库项目Greenplum DB(通 ...
- R︱Yandex的梯度提升CatBoost 算法(官方述:超越XGBoost/lightGBM/h2o)
俄罗斯搜索巨头 Yandex 昨日宣布开源 CatBoost ,这是一种支持类别特征,基于梯度提升决策树的机器学习方法. CatBoost 是由 Yandex 的研究人员和工程师开发的,是 Matri ...
- Graham扫描法
Graham扫描法求凸包的模板 运行之后可以得到存有凸包顶点的栈s和栈顶指针top,n代表总点数 这个模板我当时调了很久,主要难点有两个,一个是正确的极角排序,一个是出栈入栈的细节操作,逆时针扫描,这 ...
- debian 8.1 安装idempiere 2.1 X64 笔记
接上文.当虚拟服务器和虚拟机搭建完成后.登陆debian 8.1 X64. 进入虚拟服务器控制台.打开虚拟机.root登陆.(留好初始状态系统快照.以便系统恢复.) 由于之前debian8.1X64默 ...