单例模式小记

java中单例模式是一种常见的设计模式,单例模式分为三种:懒汉式单例、恶汉式单例和登记式单例。java

单例模式有如下特色设计模式

 一、单例只能有一个实例安全

 二、单例必须本身建立本身的惟一实例多线程

 三、单例必须给其余对象提供惟一实例app

懒汉式单例线程

public class Singleton {
	
	private static Singleton single = new Singleton();
	
	private Singleton(){}//私有化构造器
	
	public static Singleton getInstance() {
		return single;
	}
}

 

饿汉式单例设计

public class Singleton {

        private static Singleton single = null;
	
        private Singleton(){}
	
	public static Singleton getInstance() {
	    if (single == null) {
	        single = new Singleton();
	    }
	    return single;
	}
}

在单线程环境下,上面的恶汉式不存在任何问题,但在多线程环境下,线程A和B,线程A第一次进入判断single为null,而后CPU切换到线程B,B判断single也为null,此时B线程会执行new Singleton(),而后CPU切回线程A,线程A继续执行也会new Singleton(),此时就会出现两个实例,问题就出来了。code

考虑到多线程环境下多线程安全问题,高效的饿汉式修改以下cdn

public class Singleton {

        private static Singleton single = null;
	
        private Singleton(){}
	
	public static Singleton getInstance() {
	    //旨在避免实例化后其它线程在进入这个方法后进入同步代码块,提升效率
	    if (single != null) {
                return single;
	    }
    	    synchronized (Singleton.class) {
	        //第一个线程进入同步代码块,多个线程等待拿同步代码块的锁,进入同步代码块
    		//当第一个线程实例化,离开同步代码块后
		//其它等待拿同步所的线程依次进入能够直接返回实例化对象
        	if (single != null) {
        	    return single;
    		}
    		single = new Singleton();
	    }
	    return single;
	}
}

若是须要进一步提升效率能够抛弃同步代码块使用Lock锁对象

public class Singleton {

	private static Singleton single = null;
	
	private Singleton(){}
	
	public static Singleton getInstance() {
	        //旨在避免实例化后其它线程在进入这个方法后进入同步代码块,提升效率
		if (single != null) {
		    return single;
		}
		ReentrantLock lock = new ReentrantLock(false);
		try {
		    lock.lock();
		    if (single != null) {
			return single;
		    }
		    single = new Singleton();
		} catch (Exception e) {
		    System.err.println(e.getMessage());
		} finally {
		    lock.unlock();
		}
		return single;
	}
}

 

登记式单例

等级是单例这个单例实际上维护的是一组单例类的实例(父类和子类),讲这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,则从Map中获取直接返回,对于没有登记的,则先登记,再返回。

@SuppressWarnings("unchecked")
public class Singleton {

	@SuppressWarnings("rawtypes")
	private static HashMap map = new HashMap();
	
	private Singleton (){}

	static {
		Singleton single = new Singleton();
		map.put(single.getClass().getName(), single);
	}

	public static Singleton getInstance(String name) {
		if (name == null) {
			name = "Singleton";
		}
		if (map.get(name) == null) {
			try {
				map.put(name, Class.forName(name).newInstance());
			} catch (Exception e) {
				System.out.println("Error happened.");
			}
		}
		return (Singleton) map.get(name);
	}
}

其子类实现

public class SingletonChild extends Singleton {

	private SingletonChild(){}
	
	public static SingletonChild getInstance() {
		return (SingletonChild) Singleton.getInstance("SingletonChild");
	}
}
相关文章
相关标签/搜索