单例模式也叫做单肩模式,也是一种创建型模式,是我们日常开发中最常使用的一种设计模式,经常被用来封装一些工具类,例如数据库连接等。
单例模式的定义:
单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例
单例模式分为以下几种:
①饿汉单例模式
②懒汉单例模式
③IoDH单例模式
④枚举单例模式
下面我们一一的进行介绍:
1.首先是饿汉单例模式,顾名思义“饿汉”,代表急着“吃饭”(这里的饭应该是指的实例对象),所以很早就创建出来。不多说,上代码:
package singleton; public class HungrySingletonP { private static HungrySingletonP instance=new HungrySingletonP(); public HungrySingletonP(){} public static HungrySingletonP getInstance(){ return instance; } }
这段代码很形象的体现了饿汉模式。
这种方法在类加载的时候就已经实例化了(只创建唯一的实例),所以不存在线程上的一些问题。但是,也因为如此如果有太多的单例,且这些实例不经常使用那么久会造成对内存的浪费。
2.懒汉模式,同样什么叫做懒汉模式?一个懒惰的人,只有去吃饭的时候才会去刷碗(昨天用过的脏碗),即:只有当用到对象的时候才去创建对象,来上代码:
package singleton; public class LasySingletonV1 { private static LasySingletonV1 instance; public LasySingletonV1(){} public static LasySingletonV1 getInstance(){ if(instance==null){ return new LasySingletonV1(); }else return instance; } }
上面的这段代码是懒汉模式,当我们不需要实例的时候,它不会创建实例,只有需要实例的时候,才会创建,节省空间。
但是,我们不推荐使用,因为我们原来的设计理念是:当需要的时候(并且instance为空)创建实例,当已经创建过后,如果还需要实例,则判断instance是否为空,因为前边已经创建过了,不为空,所以直接返回之前已经创建的实例。
以上的想法是很好的,但是它是线程不安全的。因为:当有多个线程同时调用这个方法时,因为同时判断实例为空,所以会创建很多个实例,这不符合单例模式的设计理念(一个类只有一个实例对象)。
所以我们需要对它进行改进,因为它会异步创建多个实例,多以我们很容易就能想到,在getInstance方法之前加上synchronized进行同步:
package singleton; public class LasySingletonV2 { private static LasySingletonV2 instance; public LasySingletonV2(){} public synchronized LasySingletonV2 getInstance(){ if(instance==null){ return new LasySingletonV2(); }else return instance; } }
上面这样,就不会创建多个实例对象符合单例模式的概念。
但是上面这样的设计使得我们每次需要目标实例的时候都要排队等待,假设有很多线程都在调用这个getInstance方法,那么就会陷入很长时间的等待,大大降低的程序的效率。
所以我们还要对程序进行一定的修改,如果我们创建一个
package singleton; public class LasySingletonV3 { private static LasySingletonV1 instance; public LasySingletonV3(){} public LasySingletonV3 getInstance(){ if(instance==null){ synchronized(LasySingletonV3.class){ if(instance==null){ return new LasySingletonV3(); } } } return instance; } }
以上的方法是懒汉模式的完整版本,我们来仔细分析一下:
当有多个线程第一次调用这个方法的时候,都满足instance为空,来到下一步,先获得锁的线程进入下一步继续判断是否为空,为空,然后创建实例返回实例。
没有获得锁的线程一直等待到获得锁的线程释放锁,当在等待的线程获得锁的时候进入下一步,还要进行判断instance是否为空,但是这个时候instance已经不为空了,因为前面的线程已经创建了实例,所以返回已经创建好的实例。
以上是第一批调用getInstance方法的线程,当后续的线程调用这个方法的时候就不用进行锁的获取了和释放了,因为第一步已经判断instance不为空,直接返回instance实例。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍java 设计模式之单例模式,包括了java 设计模式之单例模式的使用技巧和注意事项,需要的朋友参考一下 java 设计模式之单例模式 前言: 在软件开发过程中常会有一些对象我们只需要一个,如:线程池(threadpool)、缓存(cache)、对话框、偏好设置等。这些对象如果制造出多个实例的话可能会导致一些不必要的麻烦,如:程序行为异常、资源使用过量等。这时单例模式就可以确保
介绍 从本章开始,我们会逐步介绍在JavaScript里使用的各种设计模式实现,在这里我不会过多地介绍模式本身的理论,而只会关注实现。OK,正式开始。 在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯
本文向大家介绍JavaScript设计模式之单例模式实例,包括了JavaScript设计模式之单例模式实例的使用技巧和注意事项,需要的朋友参考一下 《Practical Common Lisp》的作者 Peter Seibel 曾说,如果你需要一种模式,那一定是哪里出了问题。他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案。 不管是弱类型或强类型,静态或动态语言,命令式或说
单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时, 单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个 全局对象,这样有利于我们协调系统整体的行为。 --以上来自维基百科 从定义上来看,这会是一个很有用的避免冲突的设计模式,相当于把所有同样资源的调用 都交给了一个资源代理。那么 Python 中该如何实现这一模式呢? 装饰器 所有资源资源调用者都是同一个对象,我
本文向大家介绍php设计模式之单例模式代码,包括了php设计模式之单例模式代码的使用技巧和注意事项,需要的朋友参考一下 php设计模式之单例模式的例子,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家学习php程序设计有所帮助。
本文向大家介绍解析C#设计模式之单例模式,包括了解析C#设计模式之单例模式的使用技巧和注意事项,需要的朋友参考一下 单例模式(Singleton),故名思议就是说在整个应用程序中,某一对象的实例只应该存在一个。比如,一个类加载数据库中的数据到内存中以提供只读数据,这就很适合使用单例模式,因为没有必要在内存中加载多份相同的数据,另外,有些情况下不允许内存中存在多分份相同的数据,比如数据过大,内存