设计模式之单件模式
来源:互联网 发布:日本语言翻译软件 编辑:程序博客网 时间:2024/06/05 14:49
有一些对象我们只需要一个(也只能有一个)比如:线程池、cache、对话框、处理偏好设置和注册表的对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。
利用静态类变量、静态方法和适当的访问修饰符,就可以做到只存在一个实例。
这是一个经典的单件模式:
public class Singleton {private static Singleton uniqueInstance;private Singleton(){}public static Singleton getInstance(){if(uniqueInstance==null) uniqueInstance=new Singleton();return uniqueInstance; }//静态方法,引用要使用类名}
单件模式确保一个类只有一个实例,并提供一个全局访问点。
它比全局变量多了一个优点:延迟实例化。
一个巧克力工厂具有计算机控制的巧克力锅炉,只能存在一个锅炉,不然会有bad things 发生:
public class ChocolateBoiler {private boolean empty;private boolean boiled;private static ChocolateBoiler uniqueInstance;private ChocolateBoiler(){empty=true;boiled=false;}public static ChocolateBoiler getInstance(){if(uniqueInstance==null)uniqueInstance=new ChocolateBoiler();return uniqueInstance;}public void fill(){if(isEmpty()){empty=false;boiled=false;}}public void drain(){if(!isEmpty() && isBoiled())empty=true;}public void boil(){if(!isEmpty() && !isBoiled())boiled=true;}public boolean isEmpty(){return empty;}public boolean isBoiled(){return boiled;}}
但是,当我们执行以下代码时,就会发生麻烦,竟然允许在加热的过层中加入原料:
ChocolateBoiler boiler=ChocolateBoiler.getInstance();
fill();
boil();
drain();
这里有两个线程要执行这段代码,我们检查getInstance()方法中的操作次序和uniqueInstance的值就会发现,它们重叠了,产生了两个锅炉对象。
处理多线程,只要把getInstance()方法变成同步方法,可以解决:
public static synchronized ChocolateBoiler getInstance(){if(uniqueInstance==null)uniqueInstance=new ChocolateBoiler();return uniqueInstance;}
但是同步会降低性能。。。
当getInstance()的性能对应用程序不是很关键,就什么都别做。这是最直接可行的做法!
otherwise,使用急切创建实例,而不用延迟实例化的方法:
public class ChocolateBoiler {private boolean empty;private boolean boiled;private static ChocolateBoiler uniqueInstance=new ChocolateBoiler();private ChocolateBoiler(){empty=true;boiled=false;}public static ChocolateBoiler getInstance(){return uniqueInstance;}//...}
加载这个类时马上创建此唯一的单件实例。
还有一种更好的:双重检查加锁
原理是这样的,首先检查是否实例已经被创建,如果尚未创建,才进行同步。这样一来,只有第一次会同步!!!
public class ChocolateBoiler {private boolean empty;private boolean boiled;private static volatile ChocolateBoiler uniqueInstance;private ChocolateBoiler(){empty=true;boiled=false;}public static ChocolateBoiler getInstance(){if(uniqueInstance==null){synchronized (ChocolateBoiler.class) {if(uniqueInstance==null)uniqueInstance=new ChocolateBoiler();}}return uniqueInstance;}//...}
其中volatile关键词确保当uniqueInstance变量被初始化成Singleton实例时,多个线程正确处理uniqueInstance变量。
这个方法在对性能要求高的时候可以用,不然就是杀鸡用牛刀了,呵呵。
0 0
- 设计模式之单件
- C# 设计模式之单件模式
- c# 设计模式之单件模式
- 浅析设计模式之单件模式
- 设计模式 之 单件模式
- 设计模式之单件模式
- 设计模式之单件模式
- 设计模式之Singleton(单件模式)
- 设计模式之---单件模式
- c++ 设计模式之单件模式
- 设计模式之单件模式 singleton
- 设计模式之单件模式
- 设计模式之单件模式
- 设计模式 之 单件模式
- 设计模式之单件模式
- 设计模式之单件模式
- 设计模式之单件模式
- 设计模式之单件模式
- MFC打开对话框和浏览文件夹操作
- 永远都不要做的10件事
- spark 安装与运行
- Spring中的事务管理方式
- NSString属性声明中的copy和retain区别
- 设计模式之单件模式
- 第一篇博客
- python 调用linux系统命令
- 大数据之“用户行为分析”
- jQuery超酷字体显示效果
- shell中(字符串截取)
- Handler详解
- POJ训练计划1753_Flip Game(枚举+BFS)
- C/C++基本数据类型(带测试程序)