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

来源:互联网 发布:淘宝商品优惠券平台 编辑:程序博客网 时间:2024/06/06 05:09

使用场景:

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


实现流程:

      (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
原创粉丝点击