设计模式2:单例模式

单例模式

确保一个类中只有一个实例,自行实例化并向整个系统提供这个实例,这个类被称为单例类,它提供全局的访问方法

特点

在类中只有一个实例,并提供一个静态的getInstacne()方法用于外界唯一访问这个实例

防止在外部对其实例化,构造函数私有化

在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例

举例

windows操作系统中的任务管理器,回收站等,在系统中都只有一个实例,是典型的的单例模式

五种实现方式

饿汉式(线程安全)

顾名思义,既然是恶汉,肯定是饥不择食啦,所以不管三七二十一,在类加载的时候就把实例给创建出来咯

//饿汉式
public class SingletonDemo2 {
	
	private static SingletonDemo2 instance = new SingletonDemo2();
	
	//私有化构造器
	private SingletonDemo2(){
		
	}
	
	public static SingletonDemo2 getInstance(){
		
		return instance;
		
	}

}

优点:不用考虑线程同步问题

缺点:如果getInstance方法,则会造成资源浪费

懒汉式(线程安全,延时加载)

创建实例这么麻烦的事情。。当然要拖到最后一刻啦,等需要用到实例的时候再创建

//懒汉式
public class SingletonDemo1 {
	
	private static SingletonDemo1 instance;
	
	//私有化构造器
	private SingletonDemo1(){
		
	}
	
	public static synchronized SingletonDemo1 getInstance(){
		
		if(instance == null){
			instance = new SingletonDemo1();
		}
		
		return instance;
	}

}

优点:延迟加载,资源利用率提高

缺点:同步造成并发效率低

双重加锁机制

在之前的懒汉式中,它的缺点非常明显,为了保证在多线程的工作下能正常工作,它进行了同步,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。但是百分之99.9的情况下都是不需要同步的,所以它的效率是非常低的,于是我们进行优化,避免整个方法被锁,只对需要锁的代码部分加锁,可以提高执行效率。

//双重校验锁
public class SingletonDemo3 {
	
	private volatile static SingletonDemo3 instance;
	
	private SingletonDemo3(){
		
	}
	
	public static SingletonDemo3 getInstance(){
		
		if(instance == null){
			synchronized (SingletonDemo3.class) {
				if(instance == null){
					instance = new SingletonDemo3();
				}
			}
		}
		
		return instance;
	}

}

静态内部类实现

//静态内部类
public class SingletonDemo4 {
	
	
	private static class SingletonClassInstance { 
		private static final SingletonDemo4 instance = new SingletonDemo4(); 
	} 

	
	private SingletonDemo4(){
		
	}
	
	public static SingletonDemo4 getInstance(){
		
		return SingletonClassInstance.instance;
		
	}
	
}

外部类没有static属性,则不会像饿汉式那样立即加载对象。

只有真正调用getInstance(),才会加载静态内部类。加载类时是线程 安全的。 instance是static final类型,保证了内存中只有这样一个实例存在,而且只能被赋值一次,从而保证了线程安全性.

兼备了并发高效调用和延迟加载的优势!

枚举

public enum SingletonDemo5 {
    /**
    * 定义一个枚举的元素,它就代表了Singleton的一个实例。
    */
   INSTANCE;
   /**
    * 单例可以有自己的操作
    */
   public void singletonOperation(){
       //功能处理
   }
}

•优点:

–实现简单

–枚举本身就是单例模式。由JVM从根本上提供保障!避免通过反射和反序列化的漏洞!

•缺点:

–无延迟加载

总结

篇中对单例模式进行了简单介绍,同时介绍了它的五种典型的实现方式

猜你喜欢

转载自blog.csdn.net/qq_37410328/article/details/82774661
今日推荐