这段时间从头温习设计模式。记载下来,以便自己复习,也分享给大家。

[java] view plaincopy
  1. package com.iter.devbox.singleton;
  2. /**
  3. * 饿汉式
  4. * @author Shearer
  5. *
  6. */
  7. public class SingletonDemo1 {
  8. // 类的静态成员变量只初始化一次,天然是线程安全的
  9. private static final SingletonDemo1 instance = new SingletonDemo1();
  10. private SingletonDemo1(){}
  11. public static SingletonDemo1 getInstance() {
  12. return instance;
  13. }
  14. }
  15. package com.iter.devbox.singleton;
  16. /**
  17. * 懒汉式
  18. * @author Shearer
  19. *
  20. */
  21. public class SingletonDemo2 {
  22. // 类初始化时,不初始化这个对象(延迟加载,真正用的时候再创建)
  23. private static SingletonDemo2 instance;
  24. private SingletonDemo2(){}
  25. // 方法同步,调用效率低
  26. public static synchronized SingletonDemo2 getInstance() {
  27. if (null == instance)
  28. instance = new SingletonDemo2();
  29. return instance;
  30. }
  31. }
  32. package com.iter.devbox.singleton;
  33. /**
  34. * 双重检查锁实现
  35. * 将同步放到if内部,提高了执行的效率。
  36. * 不必每次获取对象时都进行同步,只有第一次才同步。
  37. * 创建了以后就没有必要了。
  38. * 问题:
  39. * 由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用。
  40. * @author Shearer
  41. *
  42. */
  43. public class SingletonDemo3 {
  44. private static SingletonDemo3 instance = null;
  45. private SingletonDemo3(){}
  46. public static SingletonDemo3 getInstance() {
  47. if (null == instance) {
  48. SingletonDemo3 sc;
  49. synchronized (SingletonDemo3.class) {
  50. sc = instance;
  51. if (null == sc) {
  52. synchronized (SingletonDemo3.class) {
  53. if (null == sc) {
  54. sc = new SingletonDemo3();
  55. }
  56. }
  57. instance = sc;
  58. }
  59. }
  60. }
  61. return instance;
  62. }
  63. }
  64. package com.iter.devbox.singleton;
  65. /**
  66. * 静态内部类实现方式(也是一种懒加载方式)
  67. * 这种方式:线程安全,调用效率高,并且实现了延迟加载
  68. * @author Shearer
  69. *
  70. */
  71. public class SingletonDemo4 {
  72. private static class SingletonClassInstance {
  73. private static final SingletonDemo4 instance = new SingletonDemo4();
  74. }
  75. // 方法没有同步,调用效率高
  76. public static SingletonDemo4 getInstance() {
  77. return SingletonClassInstance.instance;
  78. }
  79. private SingletonDemo4(){}
  80. }
  81. package com.iter.devbox.singleton;
  82. /**
  83. * 通过枚举实现单例模式(没有延迟加载)
  84. * 线程安全,调用效率高,不能延迟加载。
  85. * 并且可以天然的防止反射和反序列化漏洞
  86. * @author Shearer
  87. *
  88. */
  89. public enum SingletonDemo5 {
  90. // 枚举元素,本身就是单例对象
  91. INSTANCE;
  92. // 可以添加自己需要的操作
  93. public void singletonOperation() {
  94. System.out.println("枚举类里面的方法调用");
  95. }
  96. }

测试多线程环境下5种创建单例模式的效率

[java] view plaincopy
  1. package com.iter.devbox.singleton;
  2. import java.util.concurrent.CountDownLatch;
  3. /**
  4. * 测试多线程环境下5种创建单例模式的效率
  5. *
  6. * @author Shearer
  7. *
  8. */
  9. public class Client4 {
  10. public static void main(String[] args) throws Exception {
  11. long begin = System.currentTimeMillis();
  12. int threadNum = 100; // 100个线程(10个线程的情况下,运行多次有时候耗时为0!所以让线程多一点!)
  13. final CountDownLatch countDownLatch = new CountDownLatch(threadNum);
  14. for (int i = 0; i < threadNum; i++) {
  15. new Thread(new Runnable() {
  16. @Override
  17. public void run() {
  18. for (int i = 0; i < 100000; i++) {
  19. Object obj1 = SingletonDemo1.getInstance(); // 15.饿汉式
  20. //                      Object obj2 = SingletonDemo2.getInstance(); // 156.懒汉式
  21. //                      Object obj3 = SingletonDemo3.getInstance(); // 16.双重检查锁,不要使用!
  22. //                      Object obj4 = SingletonDemo4.getInstance(); // 15.静态内部类
  23. //                      Object obj5 = SingletonDemo5.INSTANCE; // 16.枚举实现
  24. }
  25. countDownLatch.countDown();
  26. }
  27. }).start();
  28. }
  29. /*      for (int i = 0; i < threadNum; i++) {
  30. new Thread(new MyRunnable(countDownLatch)).start();
  31. }*/
  32. countDownLatch.await(); // main线程阻塞,直到计数器变为0,才会继续往下执行
  33. long end = System.currentTimeMillis();
  34. System.out.println("总耗时:" + (end - begin));
  35. }
  36. }
  37. /*class MyRunnable implements Runnable {
  38. private CountDownLatch countDownLatch;
  39. public MyRunnable(CountDownLatch countDownLatch) {
  40. this.countDownLatch = countDownLatch;
  41. }
  42. @Override
  43. public void run() {
  44. for (int i = 0; i < 100000; i++) {
  45. //          Object obj1 = SingletonDemo1.getInstance(); // 15.饿汉式
  46. //          Object obj2 = SingletonDemo2.getInstance(); // 156.懒汉式
  47. //          Object obj3 = SingletonDemo3.getInstance(); // 16.双重检查锁,不要使用!
  48. //          Object obj4 = SingletonDemo4.getInstance(); // 31.静态内部类
  49. Object obj5 = SingletonDemo5.INSTANCE; // 16.枚举实现
  50. }
  51. countDownLatch.countDown();
  52. }
  53. }*/

选择哪种方式实现单例模式?结论:

单例对象 占用 资源 少,不需要 延迟加载:

枚举式 好于 饿汉式

单例对象 占用 资源 大,需要 延迟加载:

静态内部类式 好于 懒汉式

常用的两种方式,饿汉式和懒汉式,单例对象占用资源少时,选用饿汉式;反之,用懒汉式。

就效率来说,由于懒汉式需要同步,效率最低。

如果单例对象占用资源少,无需延迟加载,使用饿汉式或枚举式;

如果单例对象占用资源大,需要延迟加载,使用静态内部类;

本文转自http://blog.csdn.net/hardwin/article/details/51480608,所有权利归原作者所有。

单例模式的5种实现方式,以及在多线程环境下5种创建单例模式的效率相关推荐

  1. Java多线程之单例模式在多线程环境下的安全问题

    Java多线程之单例模式在多线程环境下的安全问题 目录: 单例模式基本概念 单线程下的单例模式 多线程下的单例模式 单例模式volatile分析 1. 单例模式基本概念 基本概念转载自:单例模式|菜鸟 ...

  2. Linux环境下几种常用的文件系统

    Linux环境下几种常用的文件系统: 1.ext2 ext2是为解决ext文件系统的缺陷而设计的可扩展的.高性能的文件系统,又被称为二级扩展文件系统.它是Linux文件系统中使用最多的类型,并且在速度 ...

  3. cad模型轻量化_CAD环境下一种支持大装配的产品模型轻量化技术

    CAD环境下一种支持大装配的产品模型轻量化技术 针对CAD环境下操作复杂大装配常出现加载和显示困难的问题,提出了一种CAD环境下的轻量化解决方案,将参数化表达和多细节层次(LOD)轻量表达共同定义于产 ...

  4. iphone11返回上一级手势怎么设置_华为手机的这五种导航方式,你更习惯哪一种?怎么切换?...

    手机的导航方式是人机交互的基础功能,随着智能手机进入全面屏时代,手势导航成了大家常用的系统导航方式,但也有人还是习惯于其他几种导航方式,下面就让我们一起来解读这几种导航方式. 手势导航 先来说下当下流 ...

  5. android登录加密传输,android环境下两种md5加密方式(示例代码)

    在平时开发过程中,MD5加密是一个比較经常使用的算法,最常见的使用场景就是在帐号注冊时,用户输入的password经md5加密后,传输至server保存起来.尽管md5加密经经常使用.可是md5的加密 ...

  6. 计算机系统的四种启动方式是,U盘启动有四种模式?云骑士装机大师教你怎么选...

    原标题:U盘启动有四种模式?云骑士装机大师教你怎么选 在下载云骑士装机的U盘启动盘时,我们可以看到有4种启动方式,HDD-FAT32.ZIP-FAT32.HDD-FAT16.ZIP-FAT32,有些用 ...

  7. 52、交换机的4种网络结构方式,看看你掌握了哪种

    交换机(Switch)意为"开关"是一种用于电(光)信号转发的网络设备.它可以为接入交换机的任意两个网络节点提供独享的电信号通路.最常见的交换机是以太网交换机.其他常见的还有电话语 ...

  8. python字符串字面量有哪四种定义方式_python中字符串连接的四种方式

    原博文 2018-12-05 14:28 − 以下实例展示了join()的使用方法 #!/usr/bin/python str = "-"; seq = ("a" ...

  9. mysql集群session_集群/分布式环境下5种session处理策略

    前言 在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理.如果不做任何处理的话,用户将出现频繁登录的现象,比如集群中存在A.B两台服务器,用户在第一次访问网站时,Ngin ...

最新文章

  1. FTP服务器之vsftp
  2. Approximation and fitting、Statistical estimation
  3. LsLoader——通用移动端Web App离线化方案
  4. path弧形参数 svg_SVG路径中的A指令(画弧线)
  5. java StringUtils方法全览
  6. 西安科技大学计算机学院保研,独臂姑娘,好样的!
  7. linux /proc/stat 计算线程cpu,Linux下用/proc/stat文件来计算cpu的利用率(附源码)
  8. python淘宝自动发货源码_发货100虚拟商品自动发货系统下载
  9. freyja v2版本发布
  10. 03.项目管理实践工具-团队绩效评价
  11. 以下哪些是微型计算机,2017版计算机试题及答案
  12. note GAN model
  13. vue + Element UI 动态Breadcrumb 面包屑的制作
  14. js实现单选框的选择
  15. LINUX IP 路由实现
  16. kafka日志清理策略,compact和delete
  17. 商品出库入库项目html,纯前端微型出入库管理系统(个人使用型)
  18. 股票自动委托下单html,股票怎么设置自动挂单?股票挂单的方式
  19. png四通道透明背景图成功加入到视频帧中 使用了mask原理
  20. 抓住屌丝心理才是王道

热门文章

  1. 算法笔记_132:最大流量问题(Java)
  2. (十一)Hibernate 高级配置
  3. 解决 spring mvc 3.0 结合 hibernate3.2 使用tx:annotation-driven声明式事务无法提交的问题(转载)...
  4. leetcode 42 python
  5. c# char unsigned_C 中 char、signed char 和 unsigned char 的区别
  6. 计算机辅助语文识字教学的优势,小学语文计算机辅助教学研究
  7. CCF201909-1 小明种苹果
  8. PAT乙级(1008 数组元素循环右移问题)
  9. 数据结构—链表-建立单链表
  10. 实战 | 离线搭建CDH6.20平台 踩坑实录