设计模式(二)单例模式(创建型)

使用场景:

       一个类只能创建一个实例对象。如读取服务器配置文件的类,由单个实例对象直接读取。


实现流程:

      (1)、定义一个私有变量;

      (2)、将构造函数私有化;

      (3)、提供一个获取实例的公用方法;


     下面列出几种常见的实现模式,仅供参考:

      饿汉式单例:在类创建的时候就初始化实例对象,每次调用的时候都是获取同一对象实例,是线程安全的。

      实现类:

public class HungrySingleton {
	
	private static HungrySingleton instance = new HungrySingleton();
	
	private HungrySingleton(){};
	
	public static HungrySingleton getInstance(){
		return instance;
	}

}

      测试类:

public class HungrySingletonTest {
	
	private class MyThread extends Thread{
		
		@Override  
		public void run(){
			System.out.println(HungrySingleton.getInstance().hashCode());
		}
		
	}
	
	public static void main(String[] args) {  
		MyThread[] mts = new MyThread[10];  
        for(int i = 0 ; i < mts.length ; i++){  
            mts[i] = new HungrySingletonTest().new MyThread();  
        }  
          
        for (int j = 0; j < mts.length; j++) {  
            mts[j].start();  
        }  
	}

}


      测试结果:


        从测试结果可以看出,该方式是线程安全的。


        普通懒汉式单例:创建类的时候不实例化对象,在调用获取实例方法的时候才创建对象。是线程不安全的。

        实现类:

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

}

         测试类:

public class LazySingletonTest {
	
    private class MyThread extends Thread{
		
		@Override  
		public void run(){
			System.out.println(LazySingleton.getInstance().hashCode());
		}
		
	}
    
    public static void main(String[] args) { 
		MyThread[] mts = new MyThread[10];  
        for(int i = 0 ; i < mts.length ; i++){  
            mts[i] = new LazySingletonTest().new MyThread();  
        }  
          
        for (int j = 0; j < mts.length; j++) {  
            mts[j].start();  
        }  
	}

}

        测试结果:


     从测试结果可以看出,该方式是线程不安全的。


      对线程不安全的懒汉式单例模式,有多种的解决方案。简单的如:在获取实例的公共方法里加上同步标识符synchronized。这样的话可以保证在多线程的环境下获取的实例是唯一的,但也相应地影响了效率。这里列举一种常规的解决方案——Double Check Locking双检查锁机制。


     双检查锁机制(DCL)

     实现类:

public class DclSingleton {
	
	//使用volatile保证线程间可见性
	private static volatile DclSingleton instance = null;
	
	private DclSingleton(){};
	
	public static  DclSingleton getInstance(){
		if(instance == null){
			synchronized(DclSingleton.class){
				//二次检查
				if(instance == null){
					instance = new DclSingleton();
				}
			}
		}
		return instance;
	}

}


       测试结果

    从测试结果可以看出,该方式是线程安全的,且将同步的范围限制到了最小。是推荐的一种单例实现方式。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值