博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式的5种实现方式,以及在多线程环境下5种创建单例模式的效率
阅读量:6611 次
发布时间:2019-06-24

本文共 4717 字,大约阅读时间需要 15 分钟。

hot3.png

/**  * 饿汉式  * @author yinwei.Liu *  */  public class SingletonDemo1 {            // 类的静态成员变量只初始化一次,天然是线程安全的      private static final SingletonDemo1 instance = new SingletonDemo1();            private SingletonDemo1(){}            public static SingletonDemo1 getInstance() {          return instance;      }    }       /**  * 懒汉式  * @author yinwei.Liu *  */  public class SingletonDemo2 {            // 类初始化时,不初始化这个对象(延迟加载,真正用的时候再创建)      private static SingletonDemo2 instance;            private SingletonDemo2(){}            // 方法同步,调用效率低      public static synchronized SingletonDemo2 getInstance() {          if (null == instance)              instance = new SingletonDemo2();          return instance;      }    }      /**  * 双重检查锁实现  * 将同步放到if内部,提高了执行的效率。  * 不必每次获取对象时都进行同步,只有第一次才同步。  * 创建了以后就没有必要了。  * 问题:  * 由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用。  * @author yinwei.Liu *  */  public class SingletonDemo3 {            private static SingletonDemo3 instance = null;            private SingletonDemo3(){}            public static SingletonDemo3 getInstance() {          if (null == instance) {              SingletonDemo3 sc;              synchronized (SingletonDemo3.class) {                  sc = instance;                  if (null == sc) {                      synchronized (SingletonDemo3.class) {                          if (null == sc) {                              sc = new SingletonDemo3();                          }                      }                      instance = sc;                  }              }          }          return instance;      }    }         /**  * 静态内部类实现方式(也是一种懒加载方式)  * 这种方式:线程安全,调用效率高,并且实现了延迟加载  * @author yinwei.Liu *  */  public class SingletonDemo4 {            private static class SingletonClassInstance {          private static final SingletonDemo4 instance = new SingletonDemo4();      }            // 方法没有同步,调用效率高      public static SingletonDemo4 getInstance() {          return SingletonClassInstance.instance;      }            private SingletonDemo4(){}  }         /**  * 通过枚举实现单例模式(没有延迟加载)  * 线程安全,调用效率高,不能延迟加载。  * 并且可以天然的防止反射和反序列化漏洞  * @author yinwei.Liu *  */  public enum SingletonDemo5 {      // 枚举元素,本身就是单例对象          INSTANCE;        // 可以添加自己需要的操作      public void singletonOperation() {          System.out.println("枚举类里面的方法调用");      }        }    测试多线程环境下5种创建单例模式的效率import java.util.concurrent.CountDownLatch;  /**  * 测试多线程环境下5种创建单例模式的效率  *   * @author yinwei.Liu  *  */  public class Test {        public static void main(String[] args) throws Exception {          long begin = System.currentTimeMillis();            int threadNum = 100; // 100个线程(10个线程的情况下,运行多次有时候耗时为0!所以让线程多一点!)          final CountDownLatch countDownLatch = new CountDownLatch(threadNum);            for (int i = 0; i < threadNum; i++) {              new Thread(new Runnable() {                  @Override                  public void run() {                      for (int i = 0; i < 100000; i++) {                          Object obj1 = SingletonDemo1.getInstance(); // 15.饿汉式  //                      Object obj2 = SingletonDemo2.getInstance(); // 156.懒汉式  //                      Object obj3 = SingletonDemo3.getInstance(); // 16.双重检查锁,不要使用!  //                      Object obj4 = SingletonDemo4.getInstance(); // 15.静态内部类  //                      Object obj5 = SingletonDemo5.INSTANCE; // 16.枚举实现                      }                      countDownLatch.countDown();                  }              }).start();          }            /*      for (int i = 0; i < threadNum; i++) {             new Thread(new MyRunnable(countDownLatch)).start();         }*/                    countDownLatch.await(); // main线程阻塞,直到计数器变为0,才会继续往下执行            long end = System.currentTimeMillis();          System.out.println("总耗时:" + (end - begin));      }    }    /*class MyRunnable implements Runnable {      private CountDownLatch countDownLatch;      public MyRunnable(CountDownLatch countDownLatch) {         this.countDownLatch = countDownLatch;     }      @Override     public void run() {         for (int i = 0; i < 100000; i++) { //          Object obj1 = SingletonDemo1.getInstance(); // 15.饿汉式 //          Object obj2 = SingletonDemo2.getInstance(); // 156.懒汉式 //          Object obj3 = SingletonDemo3.getInstance(); // 16.双重检查锁,不要使用! //          Object obj4 = SingletonDemo4.getInstance(); // 31.静态内部类             Object obj5 = SingletonDemo5.INSTANCE; // 16.枚举实现         }         countDownLatch.countDown();     } }*/    /*选择哪种方式实现单例模式?结论:单例对象 占用 资源 少,不需要 延迟加载:枚举式 好于 饿汉式单例对象 占用 资源 大,需要 延迟加载:静态内部类式 好于 懒汉式 常用的两种方式,饿汉式和懒汉式,单例对象占用资源少时,选用饿汉式;反之,用懒汉式。就效率来说,由于懒汉式需要同步,效率最低。如果单例对象占用资源少,无需延迟加载,使用饿汉式或枚举式;如果单例对象占用资源大,需要延迟加载,使用静态内部类;*/

 

转载于:https://my.oschina.net/u/2433960/blog/877052

你可能感兴趣的文章
springboot docker笔记
查看>>
Modbus RTU 通信工具设计
查看>>
服务化改造实践 | 如何在 Dubbo 中支持 REST
查看>>
【第8章】JVM内存管理
查看>>
在绿色的河流上
查看>>
ovirt官方安装文档 附录G
查看>>
磁盘故障小案例
查看>>
了解相关.NET Framework不同组件区别及安装知识
查看>>
ToughRADIUS快速指南
查看>>
HTML
查看>>
【转】左手坐标系和右手坐标系
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
POJ 3335 Rotating Scoreboard 半平面交
查看>>
《Gamestorming》读书笔记
查看>>
域名和网址链接被微信浏览器拦截怎么办 微信屏蔽网址打开如何解决
查看>>
使用SQL Server Analysis Services数据挖掘的关联规则实现商品推荐功能(二)
查看>>
ubuntu下安装jdk
查看>>
C/S与B/S架构比较
查看>>
XML学习总结(2)——XML简单介绍
查看>>