java单例模式的实现方式以及差异

恶汉单例模式:
/**

创新互联公司从2013年创立,先为桦甸等服务建站,桦甸等地企业,进行企业商务咨询服务。为桦甸企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

  • 恶汉单例模式,用空间换时间的思想进行对象的初始化,在多线程的情况下,故不存在线程安全问题。

    • @author Administrator
    • */
      public class WickedManSingleTon {

    private static WickedManSingleTon instance=new WickedManSingleTon();

    private WickedManSingleTon() {

    }

    public static WickedManSingleTon getIntance() {
    return instance;
    }

}

懒汉模式:

/**

  • 懒汉单例模式,用时间换空间的概念,实例化单例对象,在多线程的情况下,存在线程安全的问题。

    • @author Administrator
    • */
      public class LasyManSingleTon {

    private static LasyManSingleTon instance=null;

    private LasyManSingleTon() {

    }

    public static LasyManSingleTon getInstance() {
    if(instance==null) {
    instance=new LasyManSingleTon();
    }
    return instance;
    }

}

/**

  • 双检索实现单例模式
  • @author Administrator DCL模式的优点就是,只有在对象需要被使用时才创建,第一次判断 INSTANCE ==
  • null为了避免非必要加锁,当第一次加载时才对实例进行加锁再实例化。这样既可以节约内存空间,又可以保证线程安全。但是,由于jvm存在乱序执行功能,DCL也会出现线程不安全的情况。具体分析如下:
  • INSTANCE = new DCLInstance();
  • 这个步骤,其实在jvm里面的执行分为三步:   
  • 1.在堆内存开辟内存空间。  
  • 2.在堆内存中实例化SingleTon里面的各个参数。  
  • 3.把对象指向堆内存空间。
  • 由于jvm存在乱序执行功能,所以可能在2还没执行时就先执行了3,如果此时再被切换到线程B上,由于执行了3,INSTANCE
  • 已经非空了,会被直接拿出来用,这样的话,就会出现异常。这个就是著名的DCL失效问题。
    */
    public class DCLInstance {
    // 手写双检索
    private static DCLInstance instance = null;//优化采用volatile

    private DCLInstance() {

    }

    public static DCLInstance getInstance() {

    if (instance == null) {
        // 同步操作
        synchronized (DCLInstance.class) {
            if (instance == null) {
                // 多线程环境下可能会出现问题的地方
                instance = new DCLInstance();
            }
        }
    }
    return instance;

    }

}

/**

  • @author Administrator
  • 内部类的形式实现单例模式:
  • 静态内部类的优点是:外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存。
  • 即当SingleTon第一次被加载时,并不需要去加载SingleTonHoler,只有当getInstance()方法第一次被调用时,
  • 才会去初始化INSTANCE,第一次调用getInstance()方法会导致虚拟机加载SingleTonHoler类,
  • 这种方法不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。
  • */
    public class InerClassMakeIntance {

    private static InerClassMakeIntance instance =null;

    private InerClassMakeIntance() {

    }

    public static InerClassMakeIntance getInstance() {
    return InerInstance.t1;
    }

    private static class InerInstance {
    private static InerClassMakeIntance t1 = new InerClassMakeIntance();
    }
    }


网页名称:java单例模式的实现方式以及差异
网站链接:http://scyanting.com/article/ghjpgd.html