单例模式
来源:互联网 发布:六个字的网络流行语 编辑:程序博客网 时间:2024/06/17 07:48
保证一个类有且只有一个实例,并提供一个访问该实例的全局访问点。要提供一个全局访问点,最常用的办法便是使用类的静态方法,静态方法只能从类而不是从实例中调用。
当一个对象在系统中独一无二,只能有一个的时候,比如一个打印设备,一个进程管理器等等,在这上面,觉得有些类似于多线程锁的概念(所以后面会用到线程同步synchronized)
单例模式比较普遍的提到了3种形式(懒汉式,饿汉式,单例注册表)
//懒汉,线程不安全public class Singleton { private static Singleton singleton;//创建一个静态变量来保存类的实例 private Singleton(){}//将构造函数声明为私有,以防止外类访问,导致多次实例化 public static Singleton getInstance(){//提供一个全局访问点,返回该类的唯一实例 if(singleton==null){//检查实例是否已经存在,保证唯一性 singleton=new Singleton(); } return singleton; } }
致命的是在多线程不能正常工作
//懒汉,线程安全public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这种写法能够在多线程中很好的工作,而且看起来它也具备很好的lazy loading,但是,遗憾的是,效率很低,99%情况下不需要同步。
//饿汉public class Singleton { private static Singleton instance = new Singleton(); //提前实例化 private Singleton (){} public static Singleton getInstance() { return instance; } }
这种方式基于classloder机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到lazy loading的效果。
//双重锁(double-checked locking)public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
在不同的classloader或者虚拟机JVM下,可能会造成结果的不可预知,所以加了2重锁,volatile关键字,也是为了这个目的,声明为volatile的变量就是可能产生不可预知结果的,volatile保证变量总是从内存中拿去(好像是这样),在JDK1.5之后,双重检查锁定才能够正常达到单例效果。
单例模式的七种写法:http://cantellow.iteye.com/blog/838473
阅读全文
0 0
- 单例、单例模式
- 单例模式-多线程单例模式
- 单件模式(单例模式)
- 设计模式------单例模式
- 设计模式------单例模式
- 设计模式-单例模式
- 设计模式 - 单例模式
- 设计模式---单例模式
- 设计模式---单例模式
- PHP模式-单例模式
- 【设计模式】单例模式
- 设计模式-单例模式
- 设计模式----单例模式
- 设计模式--单例模式
- 设计模式-单例模式
- 单例模式(单子模式)
- 设计模式-单例模式
- [设计模式] 单例模式
- PAT 1048数字加密
- UnsatisfiedDependencyException
- What Kind of Friends Are You?
- java随机数生成函数
- apt-get intall(deepIn/Ubuntu)
- 单例模式
- POJ1258 解题报告
- (89)File类:创建、删除、判断、获取文件列表、文件递归
- POJ
- 用Apache Spark进行大数据处理
- 用Kali Linux获取Wifi密码
- C++中两个类相互包含引用问题
- 使用pip安装Scipy库报错解决方法
- (7)初始化和关闭roscpp节点