设计模式——单例模式
2015-08-24 16:22
274 查看
欢迎转载,请附出处:
/article/1760828.html
比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,
这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,
即在整个的打印过程中我只有一个打印程序的实例。
简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,
任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。
从上面的类图中可以看出,在单例类中有一个构造函数 Singleton ,
但是这个构造函数却是私有的(前面是“ - ”符号),
然后在里面还公开了一个 GetInstance()方法,
通过上面的类图不难看出单例模式的特点,从而也可以给出单例模式的定义
单例模式保证一个类仅有一个实例,同时这个类还必须提供一个访问该类的全局访问点。
下面来看代码:
如上面代码所示,这种写法是最不推荐的,也是因为它的线程不安全,我们来看一下测试代码和运行结果:
这里new了三个singleton,在多线程环境下可能存在多个线程判断instance==null,所以会分别new出自己的instance,这显然违背了单例模式的初衷。
接下来我们换种写法:
下面是运行结果:
为什么说是饿汉的singleton,因为如上面代码所示,在用到示例instance之前就已经把它初始化好了,虽然这里是线程安全的,但是也会影响性能,所以我们来看第三种singleton。
下面是运行结果:
如上述代码所示,这里用到了singletonHolder这个内部类,这个内部类只会在singletonHolder.instance中用到,也就是用的时候才会初始化,故称为懒汉singleton,这样既解决了多线程下不安全的问题,同时也解决了提前初始化影响的性能问题,所以是最推荐的一种写法。
/article/1760828.html
单例模式(Singleton)
首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了,比如,一台计算机上可以连好几个打印机,但是这个计算机上的打印程序只能有一个,
这里就可以通过单例模式来避免两个打印作业同时输出到打印机中,
即在整个的打印过程中我只有一个打印程序的实例。
简单说来,单例模式(也叫单件模式)的作用就是保证在整个应用程序的生命周期中,
任何一个时刻,单例类的实例都只存在一个(当然也可以不存在)。
单例模式的结构图
从上面的类图中可以看出,在单例类中有一个构造函数 Singleton ,
但是这个构造函数却是私有的(前面是“ - ”符号),
然后在里面还公开了一个 GetInstance()方法,
通过上面的类图不难看出单例模式的特点,从而也可以给出单例模式的定义
单例模式保证一个类仅有一个实例,同时这个类还必须提供一个访问该类的全局访问点。
下面来看代码:
public class Singleton1 { private static Singleton1 instance; private Singleton1(){ System.out.println("我是线程不安全的饿汉singleton"); } public static Singleton1 getSingleton1(){ if (instance==null) { instance = new Singleton1(); } return instance; } }
如上面代码所示,这种写法是最不推荐的,也是因为它的线程不安全,我们来看一下测试代码和运行结果:
线程不安全的singleton
public class SingletonTest { public static void main(String[] args){ for (int i = 0; i < 100; i++) { new Thread(new Runnable() { @Override public void run() { Singleton1.getSingleton1(); } }).start(); } } }
这里new了三个singleton,在多线程环境下可能存在多个线程判断instance==null,所以会分别new出自己的instance,这显然违背了单例模式的初衷。
接下来我们换种写法:
线程安全的饿汉singleton
public class Singleton2 { private static Singleton2 instance = new Singleton2(); private Singleton2(){ System.out.println("我是线程安全的饿汉singleton"); } public static Singleton2 getSingleton1(){ return instance; } }
下面是运行结果:
为什么说是饿汉的singleton,因为如上面代码所示,在用到示例instance之前就已经把它初始化好了,虽然这里是线程安全的,但是也会影响性能,所以我们来看第三种singleton。
线程安全的懒汉singleton
public class Singleton { private Singleton(){ System.out.println("我是线程安全的singleton"); } private static class singletonHolder{ private final static Singleton instance = new Singleton(); } public static Singleton getSingleton(){ return singletonHolder.instance; } }
下面是运行结果:
如上述代码所示,这里用到了singletonHolder这个内部类,这个内部类只会在singletonHolder.instance中用到,也就是用的时候才会初始化,故称为懒汉singleton,这样既解决了多线程下不安全的问题,同时也解决了提前初始化影响的性能问题,所以是最推荐的一种写法。
相关文章推荐
- Hadoop之HDFS文件操作
- UVa-11988 Broken Keyboard (a.k.a. Beiju Text)
- ExtJs博客前奏
- 简道云-更新日志
- activity渲染结束的判断--onWindowFocusChanged
- ODPS简介
- 【Linux命令详解】1、日期和时间―(date、cal、hwclock和clock)
- 第一章 Python and NLTK
- HDU3118Arbiter (二分图的本质(好题)+二进制枚举)
- 板子启动ubuntu无法进入命令行
- hdu 1732 Push Box(bfs)
- Lua和C++交互
- const的使用
- python-动态特性学习
- IOS集成支付宝回调的坑
- 黑马程序员_集合之Collection接口
- setMasksToBounds
- 设置Linux最大打开文件数和进程数
- 模糊背景处理--当前界面背景
- android 读取properties乱码,android studio开发