本文共 2061 字,大约阅读时间需要 6 分钟。
单例模式的定义:
在我们系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框等,事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致的结果,单例模式是为了避免重复生成同一实例对象而产生的一种模式
我们直到全局变量分为静态变量和实例变量,静态变量也可以保证该类的实例只存在一个,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。但是如果说这个对象非常消耗资源,而且在程序做某次执行中一直没用,这样就造成了资源的浪费,利用单例模式的话,我们就可以实现在需要使用的时候才创建对象,这样就避免了不必要的资源浪费
单例模式的核心就是三私一公:
饿汉单例在类加载过程中就实例化类对象,因此称为"饿汉",由于Java类加载的过程本身是线程安全的,因此饿汉式的优点是无需额外同步即线程安全,并发效率高,缺点是由于无法延迟加载,导致占用空间资源
public class singletonHungry { private static SingletonHungry instance = new SingletonHungry(); //类初始化的时候立即加载对象 private SingletonHungry() {} //私有构造方法,外部不能new public static SingletonHungry getInstance() { return instance; }}
懒汉式单例模式在第一次调用getInstance方法时才实例化对象,因此属于延迟加载的实现方式。但是getInstance方法需要用synchronized关键字同步,会降低并发效率。如果不用synchronized关键字修饰getInstance方法,在多线程的条件下会出现实例化多个对象的情况
public class SingletonLazy { private static SingletonLazy instance; //注意这里的变量一开始只是声明,并没有实例化 private SingletonLazy() {} public static synchronized SingletonLazy getInstance() { if(instance==null) { instance=new SingletonyLazy(); //调用getInstance方法后再实例化对象 } return instance; }}
利用双重检查加锁,首先检查是否实例已经创建,如果尚未创建,才进行同步,这样一来,只有一次同步
public class Singleton { //volatile保证,当静态变量被初始化成实例时,多个线程可以正确处理 private volatitle static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstance() { //检查实例,如果不存在,就进入同步代码块 if(uniqueInstance == null) { synchronized(Singleton.class) { //进入同步代码块后,再检查一次,如果仍是null,才创建实例 if(uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; }}
转载地址:http://xhjmb.baihongyu.com/