单例模式总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式总结相关的知识,希望对你有一定的参考价值。
Reference
[1] http://jiangzhengjun.iteye.com/blog/652440
[2] http://blog.sina.com.cn/s/blog_6ee97c580100opvp.html
单例类的特点:
1、单例类在整个系统中只能有一个实例
2、单例类必须自己创建自己的实例
3、单例类必须系统中其他对象提供这个实例
单例类的优点:
单例类实用举例:Windows的任务管理器,打不开两个。 网站的计数器,不然很难实现同步。 数据库连接池的设计
饿汉模式(非延迟加载)
在类加载时就立即创建对象。优点时没有加锁,执行效率高。缺点是类加载时就初始化,浪费内存。
public class SingletonOne { //Create instance when the class load. private static final SingletonOne m_instance = new SingletonOne(); //此处写成私有方法可以防止用户在外面用new方法来产生。 private SingletonOne(){} public synchronized static SingletonOne getInstance(){ return m_instance; } }
懒汉模式(同步延迟加载)
Lazy Load, 只在外部对象第一次请求实例的时候才会去创建,优点是第一次调用才会初始化,避免内存浪费。缺点是必须加锁synchronized才能保证单例。
public class SingletonTwo { private static SingletonTwo m_getInstance = null; //此处写成私有方法可以防止用户在外面用new方法来产生。 private SingletonTwo(){ } //synchronized可以保证线程安全 public synchronized static SingletonTwo getInstance(){ //When invoke the instance then create instance. if (m_getInstance == null){ m_getInstance = new SingletonTwo(); } return m_getInstance; } }
双重检测同步延迟加载
为处理原版同步延迟加载方式瓶颈问题,我们需要对 instance 进行第二次检查,目的是避开过多的同步(因为这里的同步只需在第一次创建实例时才同步,一旦创建成功,以后获取实例时就不需要同获取锁了)。
所谓双重检查加锁机制,指的是:并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法过后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块过后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。这样一来,就只需要同步一次了,从而减少了多次在同步情况下进行判断所浪费的时间。
双重检查加锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确的处理该变量。
注意:在Java1.4及以前版本中,很多JVM对于volatile关键字的实现有问题,会导致双重检查加锁的失败,因此双重检查加锁的机制只能用在Java5及以上的版本。
public class Singleton { private volatile static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ //先检查实例是否存在,如果不存在才进入下面的同步块 if(instance == null){ //同步块,线程安全的创建实例 synchronized(Singleton.class){ //再次检查实例是否存在,如果不存在才真的创建实例 if(instance == null){ instance = new Singleton(); } } } return instance; } }
改进型懒汉模式
内部类只有在外部类被调用才加载,产生SINGLETON实例,又不用加锁,此模式有上述俩模式的优点,屏蔽了他们的缺点,是最好的单例模式。
public class Singleton{ private Singleton(){} public static Singleton getInstance(){ return Holder.SINGLETON;} private static class Holder{//内部类 private static final Singleton SINGLETON= new Singleton(); } }
以上是关于单例模式总结的主要内容,如果未能解决你的问题,请参考以下文章