设计模式之单例模式
来源:互联网 发布:vba提取网页数据 编辑:程序博客网 时间:2024/04/28 08:30
定义:
确保一个类只有一个实例,并提供一个全局访问点。
简介:
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,阻止所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
首先,我们来看一下经典单例模式的实现。
如果现在有两个线程都要执行getInstance()方法,可能会出现如下情况。
从图中可以看到,这里生成了两个对象,违反了单个实例的原则。
利用这个做法,我们依赖JVM在加载这个类时马上创建此类唯一的实例。JVM保证在任何线程访问instance静态变量之前,一定会先创建此实例。
如果应用程序总是创建并使用单例,或者在创建和运行方面的负担不太繁重,可以使用该方式。
最后总结一下单例模式的要点:
1.单例模式确保程序中一个类最多只有一个实例。
2.单例模式也提供访问这个实例的全局点。
3.在Java中实现单例模式需要私有的构造器、一个静态方法和一个静态变量。
4.确定在性能和资源上的限制,然后小心的选择适当的方案来实现单例,以解决多线程的问题。
5.如果使用多个类加载器,可能导致单例失效而产生多个实例。
确保一个类只有一个实例,并提供一个全局访问点。
简介:
单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,阻止所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。
首先,我们来看一下经典单例模式的实现。
package net.csdn.blog.ruancoder;public class Singleton { // 利用一个静态变量来记录Singleton类的唯一实例 private static Singleton instance; // 这里可以添加其他有用的变量 // 把构造器声明为私有的,只有在Singleton类内才可以调用构造器 private Singleton() { } // 利用getInstance()方法实例化对象,并返回这个实例 public static Singleton getInstance() { // 如果instance是空的,表示还没有创建实例 if (instance == null) { // 利用私有的构造器产生一个Singleton实例并赋值给instance静态变量 // 如果我们不进入该方法,它就永远不会产生 instance = new Singleton(); } // 当执行到这个return,就表示我们已经有了实例,并将instance返回 return instance; } // 这里可以添加其他有用的方法}
如果现在有两个线程都要执行getInstance()方法,可能会出现如下情况。
从图中可以看到,这里生成了两个对象,违反了单个实例的原则。
那么如何解决呢?只需要把getInstance()方法变成同步(syncronized)方法,多线程灾难几乎就可以轻易地解决了。
同步getInstance()方法
package net.csdn.blog.ruancoder;public class Singleton { private static Singleton instance; private Singleton() { } // 通过增加synchronized关键字到getInstance()方法中,我们迫使每个线程在进入这个方法之前,要先等候别的线程离开该方法 // 也就是说,不会有两个线程可以同时进入这个方法 public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; }}
这种实现在解决问题的同时,会带来性能的降低。只有第一次执行此方法,才真正需要同步。换句话说,一旦设置了instance变量,就不再需要同步这个方法了。之后每次调用这个方法,同步都是一种累赘。
急切实例化
package net.csdn.blog.ruancoder;public class Singleton { // 在静态初始化器中创建单利,保证了线程安全 private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { // 已经有实例了,直接返回 return instance; }}
利用这个做法,我们依赖JVM在加载这个类时马上创建此类唯一的实例。JVM保证在任何线程访问instance静态变量之前,一定会先创建此实例。
如果应用程序总是创建并使用单例,或者在创建和运行方面的负担不太繁重,可以使用该方式。
双重检查加锁
package net.csdn.blog.ruancoder;public class Singleton { // volatile关键字,确保当instance变量被初始化成Singleton实例时,多个线程正确地处理instance变量 private volatile static Singleton instance; private Singleton() { } public static Singleton getInstance() { // 检查实例,如果不存在,就进入同步区块 if (instance == null) { // 注意,只有第一次才彻底执行这里的代码 synchronized (Singleton.class) { // 进入区块后,再检查一次,如果仍是空,才创建实例 if (instance == null) { instance = new Singleton(); } } } return instance; }}
利用双重检查加锁,首先检查实例是否已经创建了,如果尚未创建,才进行同步。这样一来,只有第一次会同步,这正是我们想要的。
如果性能是我们关心的重点,那么这个做法可以大大地减少getInstance()的时间消耗。最后总结一下单例模式的要点:
1.单例模式确保程序中一个类最多只有一个实例。
2.单例模式也提供访问这个实例的全局点。
3.在Java中实现单例模式需要私有的构造器、一个静态方法和一个静态变量。
4.确定在性能和资源上的限制,然后小心的选择适当的方案来实现单例,以解决多线程的问题。
5.如果使用多个类加载器,可能导致单例失效而产生多个实例。
0 0
- 设计模式之 单例设计模式
- 设计模式之 单例设计模式
- 设计模式之单例设计模式
- 设计模式之-----------单例设计模式
- 设计模式之:单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之单例设计模式
- 设计模式之-单例设计模式
- 设计模式之单例设计模式 标签: 设计模式
- 设计模式之单例
- 设计模式之单例
- 设计模式之 单例
- XMPP聊天之Openfire后台的安装和配置
- 初识ListView
- java 接口 抽象类 继承 重载 重写 多态
- 多态的成员(变量、方法)访问特点【非静态】
- #android#java的常用类
- 设计模式之单例模式
- 在ubuntu中配置java环境并运行java程序
- 在Service中弹出对话框
- 异常类型
- Nginx源码剖析
- ajax总结
- Android 开发中的日常积累
- Zero Defects 迷思
- hdu 3065 病毒侵袭持续中(AC自动机)