天天看点

单例模式的三种方式

饿汉式,由于对象不会变化,所以不存在多线程的问题

/**
 * 饿汉式,不会产生线程并发,但是没有实现按需加载
 * @author Administrator
 *
 */
public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton (){}
    public static Singleton getInstance() {
	    return instance;
    }
   
}
           

好处:

  1. 不会有多线程的问题
  2. 使用起来简单

不好:

  1. 一开始就初始化对象,会造成浪费
  2. 一般程序都会按照自己需要进行初始化对象
  3. 引出按需初始化对象的懒加载方式(如下)

懒汉式

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

内部类加上饿汉式实现懒加载

public class Singleton {
	/**  
     * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例  
     * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载  
     */  
    private static class SingletonHolder{   
        /**  
         * 静态初始化器,由JVM来保证线程安全  
         */  
        private static Singleton instance = new Singleton();   
    }   
    /**  
     * 私有化构造方法  
     */  
    private Singleton(){   
    }   
    public static Singleton getInstance(){   
        return SingletonHolder.instance;   
    }  
}
           

多线程检查代码

public class ThreadGetObjRun implements Runnable {

	@Override
	public void run() {
		//for(int i = 0;i<10;i++){
			System.out.println("线程ID = "+ Thread.currentThread().getId() + Singleton.getInstance());
		//}
	}
	public static void main(String[] args) {
		ThreadGetObjRun runnable = new  ThreadGetObjRun();
		ThreadGetObjRun runnable1 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable2 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable3 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable4 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable5 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable6 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable7 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable8 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable9 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable10 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable11 = new  ThreadGetObjRun();
		ThreadGetObjRun runnable12 = new  ThreadGetObjRun();
		
		Thread singletonThread = new Thread(runnable);
		Thread singletonThread1 = new Thread(runnable1);
		Thread singletonThread2 = new Thread(runnable2);
		Thread singletonThread3 = new Thread(runnable3);
		Thread singletonThread4 = new Thread(runnable4);
		Thread singletonThread5 = new Thread(runnable5);
		Thread singletonThread6 = new Thread(runnable6);
		Thread singletonThread7 = new Thread(runnable7);
		Thread singletonThread8 = new Thread(runnable8);
		Thread singletonThread9 = new Thread(runnable9);
		Thread singletonThread10 = new Thread(runnable10);
		Thread singletonThread11 = new Thread(runnable11);
		Thread singletonThread12 = new Thread(runnable12);
		singletonThread.start();
		singletonThread1.start();
		singletonThread2.start();
		singletonThread3.start();
		singletonThread4.start();
		singletonThread5.start();
		singletonThread6.start();
		singletonThread7.start();
		singletonThread8.start();
		singletonThread9.start();
		singletonThread10.start();
		singletonThread11.start();
		singletonThread12.start();
	}
}