单例模式的几个特征:

1、构造私有

2、对象私有、静态。

3、存在一个调用对象的公共静态方法。

 

 

懒汉模式

package com.singleton;

public class SingletonLazy {
	private  static SingletonLazy singletonLazy;
	
	private  SingletonLazy() {
	}
	
	
	public static  synchronized SingletonLazy singletonLazyInstance(){
		if(singletonLazy==null){
			singletonLazy = new SingletonLazy();
		}
		return singletonLazy;
	}
	
}

 

饿汉模式

package com.singleton;

public class SingletonHungry {
	
	private  final static  SingletonHungry singletonHungry = new SingletonHungry();
	
	private SingletonHungry(){
		
	}
	
	public static SingletonHungry  getSingletonHungry(){
		return singletonHungry;
	}
}

 

静态内部类加载模式

package com.singleton;

public class SingletonClass {
	private static class SingletonClassStatic{
		private static final SingletonClass SINGLETON_CLASS_STATIC= new SingletonClass();
	}
	
	private SingletonClass(){}
	
	public static  SingletonClass getSingleton(){
		return SingletonClassStatic.SINGLETON_CLASS_STATIC;
	}

}

 

调度快慢:饿汉式>内部类加载>懒加载

空间效率:懒加载>内部类加载>饿汉式

 

注意:没有加锁的懒汉式是线程不安全的。

 

测试

package com.singleton;

public class Client {
	public static void main(String[] args) {
		
		/*
		 * 
		 * SingletonLazy singletonLazy1 = SingletonLazy.singletonLazyInstance();
		SingletonLazy singletonLazy2 = SingletonLazy.singletonLazyInstance();
		
		System.out.println(singletonLazy1 == singletonLazy2);
		
		long start  = System.currentTimeMillis();
		for (int i = 0; i < 10; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					for (int j = 0; j < 10000000; j++) {

						Object singletonLazy = SingletonLazy.singletonLazyInstance();
					}
				}
			}).start();                       
		}
		long end  = System.currentTimeMillis();
		System.out.println(end-start);
		 * */
	
		
	/*
	 * 
	 * 
	 * SingletonHungry singletonHungry = SingletonHungry.getSingletonHungry();
	SingletonHungry singletonHungry2 = SingletonHungry.getSingletonHungry();
	
	System.out.println(singletonHungry==singletonHungry2);
	
	
	long start  = System.currentTimeMillis();
	for (int i = 0; i < 10; i++) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				for (int j = 0; j < 10000000; j++) {

					Object o = singletonHungry.getSingletonHungry();
				}
			}
		}).start();                       
	}
	long end  = System.currentTimeMillis();
	System.out.println(end-start);
	
	 * */	
		
		
		SingletonClass singletonClass = SingletonClass.getSingleton();
		SingletonClass singletonClass2 = SingletonClass.getSingleton();
		System.out.println(singletonClass2==singletonClass);
		
		
	}
}