单例模式的5种实现方式,以及在多线程环境下5种创建单例模式的效率
这段时间从头温习设计模式。记载下来,以便自己复习,也分享给大家。
- package com.iter.devbox.singleton;
- /**
- * 饿汉式
- * @author Shearer
- *
- */
- public class SingletonDemo1 {
- // 类的静态成员变量只初始化一次,天然是线程安全的
- private static final SingletonDemo1 instance = new SingletonDemo1();
- private SingletonDemo1(){}
- public static SingletonDemo1 getInstance() {
- return instance;
- }
- }
- package com.iter.devbox.singleton;
- /**
- * 懒汉式
- * @author Shearer
- *
- */
- public class SingletonDemo2 {
- // 类初始化时,不初始化这个对象(延迟加载,真正用的时候再创建)
- private static SingletonDemo2 instance;
- private SingletonDemo2(){}
- // 方法同步,调用效率低
- public static synchronized SingletonDemo2 getInstance() {
- if (null == instance)
- instance = new SingletonDemo2();
- return instance;
- }
- }
- package com.iter.devbox.singleton;
- /**
- * 双重检查锁实现
- * 将同步放到if内部,提高了执行的效率。
- * 不必每次获取对象时都进行同步,只有第一次才同步。
- * 创建了以后就没有必要了。
- * 问题:
- * 由于编译器优化原因和JVM底层内部模型原因,偶尔会出问题,不建议使用。
- * @author Shearer
- *
- */
- 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;
- }
- }
- package com.iter.devbox.singleton;
- /**
- * 静态内部类实现方式(也是一种懒加载方式)
- * 这种方式:线程安全,调用效率高,并且实现了延迟加载
- * @author Shearer
- *
- */
- public class SingletonDemo4 {
- private static class SingletonClassInstance {
- private static final SingletonDemo4 instance = new SingletonDemo4();
- }
- // 方法没有同步,调用效率高
- public static SingletonDemo4 getInstance() {
- return SingletonClassInstance.instance;
- }
- private SingletonDemo4(){}
- }
- package com.iter.devbox.singleton;
- /**
- * 通过枚举实现单例模式(没有延迟加载)
- * 线程安全,调用效率高,不能延迟加载。
- * 并且可以天然的防止反射和反序列化漏洞
- * @author Shearer
- *
- */
- public enum SingletonDemo5 {
- // 枚举元素,本身就是单例对象
- INSTANCE;
- // 可以添加自己需要的操作
- public void singletonOperation() {
- System.out.println("枚举类里面的方法调用");
- }
- }
测试多线程环境下5种创建单例模式的效率
- package com.iter.devbox.singleton;
- import java.util.concurrent.CountDownLatch;
- /**
- * 测试多线程环境下5种创建单例模式的效率
- *
- * @author Shearer
- *
- */
- public class Client4 {
- 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();
- }
- }*/
选择哪种方式实现单例模式?结论:
单例对象 占用 资源 少,不需要 延迟加载:
枚举式 好于 饿汉式
单例对象 占用 资源 大,需要 延迟加载:
静态内部类式 好于 懒汉式
常用的两种方式,饿汉式和懒汉式,单例对象占用资源少时,选用饿汉式;反之,用懒汉式。
就效率来说,由于懒汉式需要同步,效率最低。
如果单例对象占用资源少,无需延迟加载,使用饿汉式或枚举式;
如果单例对象占用资源大,需要延迟加载,使用静态内部类;
本文转自http://blog.csdn.net/hardwin/article/details/51480608,所有权利归原作者所有。
单例模式的5种实现方式,以及在多线程环境下5种创建单例模式的效率相关推荐
- Java多线程之单例模式在多线程环境下的安全问题
Java多线程之单例模式在多线程环境下的安全问题 目录: 单例模式基本概念 单线程下的单例模式 多线程下的单例模式 单例模式volatile分析 1. 单例模式基本概念 基本概念转载自:单例模式|菜鸟 ...
- Linux环境下几种常用的文件系统
Linux环境下几种常用的文件系统: 1.ext2 ext2是为解决ext文件系统的缺陷而设计的可扩展的.高性能的文件系统,又被称为二级扩展文件系统.它是Linux文件系统中使用最多的类型,并且在速度 ...
- cad模型轻量化_CAD环境下一种支持大装配的产品模型轻量化技术
CAD环境下一种支持大装配的产品模型轻量化技术 针对CAD环境下操作复杂大装配常出现加载和显示困难的问题,提出了一种CAD环境下的轻量化解决方案,将参数化表达和多细节层次(LOD)轻量表达共同定义于产 ...
- iphone11返回上一级手势怎么设置_华为手机的这五种导航方式,你更习惯哪一种?怎么切换?...
手机的导航方式是人机交互的基础功能,随着智能手机进入全面屏时代,手势导航成了大家常用的系统导航方式,但也有人还是习惯于其他几种导航方式,下面就让我们一起来解读这几种导航方式. 手势导航 先来说下当下流 ...
- android登录加密传输,android环境下两种md5加密方式(示例代码)
在平时开发过程中,MD5加密是一个比較经常使用的算法,最常见的使用场景就是在帐号注冊时,用户输入的password经md5加密后,传输至server保存起来.尽管md5加密经经常使用.可是md5的加密 ...
- 计算机系统的四种启动方式是,U盘启动有四种模式?云骑士装机大师教你怎么选...
原标题:U盘启动有四种模式?云骑士装机大师教你怎么选 在下载云骑士装机的U盘启动盘时,我们可以看到有4种启动方式,HDD-FAT32.ZIP-FAT32.HDD-FAT16.ZIP-FAT32,有些用 ...
- 52、交换机的4种网络结构方式,看看你掌握了哪种
交换机(Switch)意为"开关"是一种用于电(光)信号转发的网络设备.它可以为接入交换机的任意两个网络节点提供独享的电信号通路.最常见的交换机是以太网交换机.其他常见的还有电话语 ...
- python字符串字面量有哪四种定义方式_python中字符串连接的四种方式
原博文 2018-12-05 14:28 − 以下实例展示了join()的使用方法 #!/usr/bin/python str = "-"; seq = ("a" ...
- mysql集群session_集群/分布式环境下5种session处理策略
前言 在搭建完集群环境后,不得不考虑的一个问题就是用户访问产生的session如何处理.如果不做任何处理的话,用户将出现频繁登录的现象,比如集群中存在A.B两台服务器,用户在第一次访问网站时,Ngin ...
最新文章
- FTP服务器之vsftp
- Approximation and fitting、Statistical estimation
- LsLoader——通用移动端Web App离线化方案
- path弧形参数 svg_SVG路径中的A指令(画弧线)
- java StringUtils方法全览
- 西安科技大学计算机学院保研,独臂姑娘,好样的!
- linux /proc/stat 计算线程cpu,Linux下用/proc/stat文件来计算cpu的利用率(附源码)
- python淘宝自动发货源码_发货100虚拟商品自动发货系统下载
- freyja v2版本发布
- 03.项目管理实践工具-团队绩效评价
- 以下哪些是微型计算机,2017版计算机试题及答案
- note GAN model
- vue + Element UI 动态Breadcrumb 面包屑的制作
- js实现单选框的选择
- LINUX IP 路由实现
- kafka日志清理策略,compact和delete
- 商品出库入库项目html,纯前端微型出入库管理系统(个人使用型)
- 股票自动委托下单html,股票怎么设置自动挂单?股票挂单的方式
- png四通道透明背景图成功加入到视频帧中 使用了mask原理
- 抓住屌丝心理才是王道
热门文章
- 算法笔记_132:最大流量问题(Java)
- (十一)Hibernate 高级配置
- 解决 spring mvc 3.0 结合 hibernate3.2 使用tx:annotation-driven声明式事务无法提交的问题(转载)...
- leetcode 42 python
- c# char unsigned_C 中 char、signed char 和 unsigned char 的区别
- 计算机辅助语文识字教学的优势,小学语文计算机辅助教学研究
- CCF201909-1 小明种苹果
- PAT乙级(1008 数组元素循环右移问题)
- 数据结构—链表-建立单链表
- 实战 | 离线搭建CDH6.20平台 踩坑实录