设计模式——单例模式
2016-05-01 11:58
330 查看
单例模式
若一个类在整个程序的运行期间仅能有一个实例,则多个线程对此实例的访问必须考虑线程安全的问题。对于一些互斥性的唯一性的资源类,通常使用单例模式,从而防止进入不一致状态。单线程环境下的懒汉式单例
//该方法在多线程下可能会创建出多个实例,由此仅适用于单线程环境 public class Singleton { //私有静态成员,属于类的成员,一个类就这么一个 private static Singleton single = null; //私有构造方法,仅能内部自己使用,外界无法访问,由此外界无法创建该类的实例 private Singleton() { ... } //对外提供的公共接口,返回类的唯一实例 public static Singleton getInstance() { if(single == null) { //多个线程可能会同时进入此方法,从而导致多例 single = new Singleton(); } return single; } }
多线程下的懒汉式单例
public class Singleton { private static Singleton single = null; private Singleton () { ... } //关键字synchronized修饰的方法,同一时刻只能有一个线程进入访问。在线程退出该方法之前,其它任何线程不能进入访问 public static synchronized Singleton getInstance() { if(single == null) { single = new Singleton(); } return single; } }
上述直接给整个方法加锁,每次执行都要同步。若加锁之前先判断实例是否为空,为空时才会加锁同步,不为空时不需要加锁同步,可保证仅在第一次创建实例的时候同步,以后不会再同步,效率明显提高。
synchronized(Object) { //参数Object为对象锁。任何一个Object子类的对象都可以作为对象锁。一个线程必须持有对象锁才可以进入代码块执行。 ... }
对象锁肯定是synchronized(Object) {…}代码块所属的类的一个成员。这个成员应该是静态的,属于类,为类的唯一成员,被类的全部实例共享。若对象锁为普通成员,则每个类的实例都有一个自己的对象锁,那不同的线程使用同一个类的不同的实例的时候不能保证线程安全。可以者直接定义一个静态对象来作为对象锁使用,如:
public static Object o = new Object(),synchronized(o) {...}
public class Singleton { private static Singleton single = null; private Singleton () { ... } public static Singleton getInstance() { //最外层的判空,是为了明确是否需要同步操作,这一步可能会有多个线程同时进入 if(single == null) { //使用Singleton类内的静态Class类型的实例作为锁,这一步只能有一个线程进入,谁获得了锁,谁就能进入 synchronized(Singleton.class) { //获得锁后,要进一步判空,因为可能有多个进程都进入了之前的同步操作。第一个进程得到锁进入判空创建实例后,释放锁。第二个进程进入判空后,判空无需再创建实例 if(single == null) { single = new Singleton(); } } } return single; } }
多线程下的饿汉式单例
在类加载的时候就直接创建类的实例,直接省去了同步的操作。静态成员在类加载的时候会初始化。普通成员在创建类的实例的时候才会初始化,因为它们属于实例不属于类。public class Singleton { //静态成员隶属类,加载即初始化。定义为final,初始化后不可再改变或初始化 private static final Singleton INSTANCE = new Singleton(); private Singleton() { ... } public static Singleton getInstance() { return INSTANCE; } }
相关文章推荐
- Strong Components
- leetcode——114—— Flatten Binary Tree to Linked List
- hdu5676 ztr loves lucky numbers DFS+二分
- Ubuntu16.04 卸载VMware12
- wince工业屏下QT开发环境搭建
- Linux之玩转xargs
- java之Collection接口
- Sublime Text 2 -Sidebar 背景色调整为黑色攻略
- UVa 10129 Play On Words
- ubuntu16.04 wps不能使用搜狗输入法
- LeetCode 96.Unique Binary Search Trees
- matlab小数取整函数
- XMG 偏好设置存储
- java中instanceof用法
- python基础教程
- volatile 和sig_atomic_t
- BootStrap glyphicons 字体图标实现方法
- ssm框架配置要点
- 解决绝对定位居中的问题
- 第 26 章 CSS3 动画效果