设计模式:单例模式
来源:互联网 发布:二维图形变换矩阵 编辑:程序博客网 时间:2024/05/16 12:26
原文地址:http://leihuang.org/2014/12/05/singleton/
Creational 模式
物件的产生需要消耗系统资源,所以如何有效率的产生、管理 与操作物件,一直都是值得讨论的课题, Creational 模式即与物件的建立相关,在这个分类下的模式给出了一些指导原则及设计的方向。下面列举到的全属于Creational 模式
- Simple Factory 模式
- Abstract Factory 模式
- Builder 模式
- Factory Method 模式
- Prototype 模式
- Singleton 模式
- Registry of Singleton 模式
当程序中要求只需要一个单例的时候,那么此时就需要使用单例模式,如果没有这种要求,那么就不需要使用单例模式.
懒汉式和饿汉式
我们先来两个常见的单例模式,懒汉式和饿汉式.
//懒汉式public class SingletonLazy { private static SingletonLazy single = null ; private SingletonLazy(){ } synchronized public static SingletonLazy getInstance(){ if(single == null){ single = new SingletonLazy() ; } return single ; } }//饿汉式public class SingletonHunger { private static SingletonHunger single = new SingletonHunger() ; private SingletonHunger(){ } public static SingletonHunger getInstatnce(){ return single ; }}
注意,懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境.
优化版的饿汉式
其实单例模式很简单,但是它涉及到的很多知识就非常复杂了.比如饿汉式虽然解决了多线程安全的问题,不需要使用同步(提高了效率),但是它 却浪费了内存,因为SingletonHunger类装载的时候就初始化了对象,此时我们就可以利用内部类的机制来解决这个问题.
public class SingletonInner { private static InnerInstance{ private static SingletonInner single = new SingletonInner() ; } private SingletonInner(){ } public static SingletonInner getInstance(){ return InnerInstance.single ; }}
上面的代码中又涉及到不少知识.
- 内部类声明为static的意义:不需要初始化外部内的情况下就能被使用;
- 内部类在自己被使用的时候才会被装载,外部内被初始化,但其内部类并未被初始化.详见这里
- 类什么时候被加载/类加载时机:第一:生成该类对象的时候,会加载该类及该类的所有父类;第二:访问该类的静态成员的时候;第三:class.forName("类名");
优化版的懒汉式
我们知道懒汉式对于饿汉式的有点在于节约了空间,但其利用同步来解决线程安全性问题,很大程度的降低了程序的效率.
于是我们就想到如何来提高懒汉式的效率,首先它依然还是必须要有同步在里面.
有一种方法就双重检查机制,这个广泛应用在c语言中,但是它在java中却是错误的,如果你上锁的是基本类型的话,是没有问题的,但是你如果锁定的是对象的话就有问题了.但是我们此处是讲单例模式,所以锁的肯定是对象而不是int,long,double等类型数据了.
如下代码是错误的.
public class SingletonLazy01 { private static SingletonLazy01 single = null ; private SingletonLazy01(){ } public static SingletonLazy01 getInstance(){ if(single == null){ synchronized(SingletonLazy01.class){ if(single == null){ single = new SingletonLazy01() ; } } } return single ; }}
我们利用volatile关键字
public class SingletonLazy01 { private volatile static SingletonLazy01 single = null ; private SingletonLazy01(){ } public static SingletonLazy01 getInstance(){ if(single == null){ synchronized(SingletonLazy01.class){ if(single == null){ single = new SingletonLazy01() ; } } } return single ; }}
至于双重检查问题详见这里--->双重检查锁定与延迟初始化
2014-12-05 19:52:59
Brave,Happy,Thanksgiving !
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 设计模式-单例模式
- [设计模式] 单例模式
- 设计模式--单例模式
- 设计模式---单例模式
- 设计模式--单例模式
- 设计模式 -----单例模式
- 设计模式:单例模式
- 黑马程序员——OC语言核心语法
- Codeforces Round #277 (Div. 2)D题
- java并发编程(四)同步工具类
- Mac版Cornerstone破解方法
- cocos2d-x 2.2.0 控制lua脚本加载时的搜索路径
- 设计模式:单例模式
- memcache缺点
- C 语言程序设计实践 3.14 摆火柴棒
- leetcode之Clone Graph
- QT我的简易记事本
- 医学领域的大数据
- 统计会撒谎:要人命的平均值!
- Java中JDK的命令行工具
- HTTP和FTP返回值大全(中文翻译稿)