2017114--单例模式的实现方式

PS:这是一个小白的学习记录之路。大神看见不要笑,狮虎看见不要生气的哈。

题目:单例模式的实现方式

解决思路:狮虎说不知道就要问度娘(PS:狮虎,不要打了,疼···我真的不知道单例)

解决步骤:狮虎说不知道就要多学习(PS:我认真的抄了一遍,狮虎,我真的很认真的抄了~)

答案:maybe~可能大概,狮虎·····别·····打·····我

首先,对于不懂什么是单例的我来说,java的单例模式是一种常见的设计模式。

单例模式定义:确保某个类只有一个实例,而且自行能够实例化并向整个系统提供这个实例。

可以被设计单例模式的对象:线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序等或多或少具有资源管理器的功能的对象

单例的特点:

单例类只有一个实例;单例类必须自己创建自己的唯一实例;单例类必须给所有其他对象提供这一实例;

单例的模式:饿汉模式;懒汉模式;双重检查模式;静态内部类单例模式;使用容器实现单例模式

1:饿汉模式:

代码如下:

public class Singleton {

private static Singleton instance = new  Singleton();

private Singleton(){

}

public static  Singleton getInstance(){

return instance;

}

}

 

PS:此种单例方法,在加载类的时候已完成实例化,因此会加载类的时间比较慢,调用此类调用类方法需要的时间较短,可避免多线程同步问题。

2:懒汉模式(线程不安全)

public class Singleton {

private static Singleton instance;

private Singleton (){

}

public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

 

PS:此方法实现了懒调用,节约了资源,但用户第一次调用的时候需要实例化,反应稍慢。在多线程无法正常使用。

3:懒汉模式(安全)

public class Singleton {

private static Singleton instance;

private Singleton (){

}

public static synchronized Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

 

PS:这种方法虽然实现了在多线程可以使用,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,所以不建议用这种模式。

4. 双重检查模式 (DCL)

public class Singleton {

private volatile static Singleton instance = new  Singleton();

private Singleton(){}

public static  Singleton getInstance(){

if(instance==null){

synchronized (Singleton.class){

if(instance==null){

instance=new Singleton();

}

}

}

return instance;

}

}

PS:此方法在getSingleton方法中对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。DCL优点是资源利用率高,第一次执行getInstance时单例对象才被实例化,效率高。缺点是第一次加载时反应稍慢一些,在高并发环境下也有一定的缺陷,虽然发生的概率很小。DCL虽然在一定程度解决了资源的消耗和多余的同步,线程安全等问题,但是他还是在某些情况会出现失效的问题,也就是DCL失效。

5. 静态内部类单例模式

public class Singleton {

private Singleton(){

}

public static  Singleton getInstance(){

return SingletonHolder.sInstance;

}

private static class  SingletonHolder{

private static final Singleton  sInstance=new  Singleton();

}

}

PS:第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,推荐使用此种单例模式。

6. 枚举单例

public enum Singleton {

INSTANCE;

public void doSomeThing() {

}

}  

PS:默认枚举实例的创建是线程安全的,并且在任何情况下都是单例

PS:杜绝单例对象被反序列化是重新生成对象代码

private Object readResolve() throws ObjectStreamException{

return singleton;

}

7:使用容器实现单例模式

public class SingletonManager{private static MapobjMap=new HashMap();

private Singleton(){

}

private static void  registerService( String key,  Object instance){

if(!objMap.containsKey(key)){

objMap.put(key, instance) ;

}

}

public static  Object getService(String key){

return objMap.get(key);

}

}

PS:用SingletonManager 将多种的单例类统一管理,在使用时根据key获取对象对应类型的对象。这种方式使得我们可以管理多种类型的单例,并且在使用时可以通过统一的接口进行获取操作,降低了用户的使用成本,也对用户隐藏了具体实现,降低了耦合度。

 

 

PS:好多好多,笔记先记在这里,后面续继续理解记忆。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容