单例模式(Singleton Pattern)

单例模式定义:Ensure a class has only one instance,and provide a global point of access to it.(确保某一个类只有一个实例,自行实例化并提供一个全局访问点)

实现一

对getInstance()方法进行同步 ,线程安全,影响性能

public class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){}
	
	public synchronized static Singleton getInstance(){
		if(null == instance){
			instance = new Singleton();
		}
		return instance;
	}
}
public class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){}
	
	public static Singleton getInstance(){
		synchronized(Singleton.class){
			if(null == instance){
				instance = new Singleton();
			}
			return instance;
		}
	}
}

 

实现二

这种实现方式的问题是单例对象是在类初始化时完成初始化,如果单例对象的创建需要消耗较多的资源,创建完成后又不立即使用,将造成系统资源严重浪费

public class Singleton {
	private static Singleton instance = new Singleton();
	//private final static Singleton instance = new Singleton();也是可以的
	
	private Singleton(){}
	
	public static Singleton getInstance(){
		return instance;
	}
}

instance的创建过程是线程安全的,详见:http://blog.csdn.net/a19881029/article/details/17068191

 

实现三(这种实现方式被称为Initialization on demand holder):

通过使用内部类,避免在类初始化时创建单例对象,而是将单例对象的创建推迟至第一次请求单例对象时完成,以达到延迟加载的效果。同时单例对象作为内部类的静态属性,这样可以保证单例对象的创建过程是线程安全的

这种实现方式的优势在于使用“延迟加载”的方式解决了实现二中单例对象创建过早浪费系统资源的问题

public class Singleton {
	private Singleton(){}
	
	private static class LazyLoad{
		private static final Singleton instance = new Singleton();
	}
	
	public static Singleton getInstance(){
		return LazyLoad.instance;
	}
}

 

我们可以对单例模式进行一些改进,比如连接池在某种程度上是不是也可以看出是“单例”的?

public class Connection {
	private static int max_num = 10;
	private static int num_count = 0;
	private static Vector<Connection> connPool = new Vector<Connection>();
	
	static{
		for( ; num_count < max_num ; num_count++){
			Connection conn = new Connection();
			System.out.println(num_count+":"+conn.hashCode());
			connPool.add(conn);
		}
	}
	
	private Connection(){}
	
	public static Connection getConn() throws Exception{
		Random random = new Random();
		int num = random.nextInt(max_num);
		Connection conn = connPool.get(num);
		System.out.println(conn.hashCode());
		return conn;
	}
	
	public static void main(String[] args) throws Exception{
		for(int i = 0 ; i<5 ; i++){
			Connection.getConn();
		}
	}
}
0:3526198 
1:7699183 
2:14285251 
3:10267414 
4:27553328 
5:4072869 
6:1671711 
7:11394033 
8:4384790 
9:9634993 
10267414
1671711
1671711
4072869
4384790

 

你可能感兴趣的:(设计模式,单例模式)