单例模式:保证一个类仅有一个实例,并提供一个访问其实例的一个全局访问点
根据单例模式的定义,写一个单例模式的例子需要注意两点:
1.实例有该类自己生成
为了防止客户代码通过 new Singleton()来实例一个对象,需要将 Singleton的默认构造函数定义为private
2. 提供一个访问其实例的全局访问点
将访问方法getInstance()定义为 static ,则直接通过Singleton.getInstance() 来获取到实例
3.单例只能有一个实例
在Singleton类中,将instance 定义为 static ,则保证了不管多少个 Singleton都只有并仅有一个instance 静态变量。
单例的实现有两种方式:
饿汉单例:在类被加载时就初始化实例
懒汉单例:类加载之后,第一次调用getInstance()方法时,才初始化实例。
不过懒汉式单例的getInstance() 方法需要注意到线程的同步问题:在单例类已经被加载进来,但还没有被调用生成实例之前,有多个线程同时调用getInstance() 方法,那么则可能多次调用 instance = new Singelton_lazy()语句,导致出现多个实例的结果。
所以懒汉单例的getInstance() 方法要使用synchronized 来保证其线程安全性。
现在我们来模拟懒汉单例模式的getInstance() 如果不注意线程安全性时出现的线程不安全现象:
现在将Singleton_lazy 改变一下: 1. 去掉synchronized
2. 认为的改变getInstance() 方法,但传入的参数为0时,则访问SingletonFull的线程需要休眠500毫秒, 当500毫秒一过,则返回一个单例的实例
现在编写两个线程类:
编写测试用的代码:
输出结果:
从输出结果中,我们可以看到Mythread 和 Mythread2 两个线程先后访问getInstance()方法,Mythread 在访问getInstance ()时,因为带了参数 0, 所以getInstance()在还没有建立单例实例时停顿了500毫秒。而在这短时间里,Mythread2 趁虚而入,访问 getInstance()方法,立马生成一个单例实例,并返回给Mythread2 。之后500毫秒过了,Mythread所访问的getInstance 线程苏醒,继而执行 instance = new SingletonFull() 方法,返回另外一个单例实例。
那么换个思路,我是否可以将测试用的代码换成:
SingletonFull sFull = SingletonFull.getInstance(0);
SingletonFull sFull2 = SingletonFull.getInstance(1);
System.out.println(sFull);
System.out.println(sFull2);
结果显示只生成了一个单例实例,为什么呢?
前面提到了在SingletonFull 中的 Thread.currentThread.sleep(500),是使访问Singleton 类的线程休眠,而不是让SingletonFull 休眠,而且SingletonFull 不是线程类,无法休眠。
通过将getInstance() 修改成下面的代码,仅仅是添加了一个输出当前访问SingletonFull 类的线程名字。
接着改变测试代码,也添加了一条输出当前线程名称的代码
最后结果输出:
从结果中可以看到在整个测试代码运行过程中,只有main 线程在运行。并且这里,由于main线程先休眠了500毫秒,然后才依次打印出单例实例的名称。而在前面的测试代码中,程序一执行,就先输出了一个单例实例名称,过了500毫秒后,才输出另外一个单例实例名称。
分享到:
相关推荐
代理模式学习笔记、单例模式学习笔记、命令模式、原型模式、模式特点总结。 为个人对设计模式的理解,如果有理解不一致的不要砸砖啊
该资料介绍Java各类开发模式,包含以下教程:《深入浅出设计模式(中文版)》《Java单例模式》《Java设计模式-图解-附代码》《JAVA设计模式之单例模式(完整版)》《Java学习笔记(必看经典)》《Java总复习》《单例模式》...
本课程是使用Java来讲解设计模式,考虑到设计模式比较抽象,授课采用 图解+框架源码分析的方式 1) 内容包括: 设计模式七大原则(单一职责、接口隔离、依赖倒转、里氏替换、开闭原则、迪米特法则、合成复用)、UML...
我是清风~,每天学习一点点,快乐成长多一点,这些都是我的日常笔记以及总结。 目录单例模式懒汉式单例模式未初始化问题解决Double Check 双重检查方案一:不让第二步和第三步重排序-DoubleCheck方案二:基于类初始...
设计模式是一种解决软件设计问题的经验总结,是在软件开发过程中经过反复验证的最佳实践。设计模式提供了一套通用的解决方案,可以帮助开发人员更好地组织和设计代码,提高代码的可读性、可维护性和可扩展性。 设计...
今天听完狂神说java的单例模式,感慨万分。希望通过这篇文章跟大家一起学习。 1. 饿汉式 [1] 一个私有的构造器 [2] 一个静态变量 [3] 一个静态方法返回对象 饿汉式单例是直接使用静态变量的方式生成这个单例对象...
本文实例讲述了Javascript面向对象程序设计单例模式原理与实现方法。分享给大家供大家参考,具体如下: 1.单例模式概述 源自百度百科对于单例模式的定义: 单例模式的意思就是只有一个实例。单例模式确保某一个类...
酒店管理客房系统Java源码 创建型模式:关注对象的创建过程 :保证一个类只有一个实例,并且提供一个访问该实例的全局访问点 主要: 饿汉式(线程安全,调用效率高,但是不能延时加载) 懒汉式(线程安全,调用效率...
抽象类--模板设计模式 9 接口 9 内部类 11 匿名内部类的使用(重要!!!!!!!) 13 成员内部类的使用 13 静态内部类的使用 14 枚举的二种实现方式 14 自定义类实现枚举 14 使用 enum 关键字实现枚举注意事项 15 enum 用...
参考书籍(推荐): 《Java设计模式 - 刘伟》 , 《图解设计模式 - [日]结城浩》 创建型模式 :check_mark:简单工厂模式( Simple Factor Pattern ) :memo: , :check_mark:工厂方法模式( Factory Method Pattern )...
java核心技术-多线程的概念及多线程单例设计模式的应用-懒汉模式、饿汉模式、优化懒汉
学习笔记较长,如果想查看文章的目录,chrome浏览器可以配合简悦插件使用,或者下载到本地使用Typora打开。 :hot_beverage: Java基础 Java容器 Java并发 数据结构和算法 数据结构 树 图 算法 分治 动态规划 回溯 ...
describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...
Java Design Patterns 学习笔记 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元...
避坑笔记2021CICDCI/CD流程以及原理说明设计模式:策略模式单例模式工厂模式装饰器模式观察者模式适配器模式模板方法模式SpringBoot:SpringBoot(1):公共配置SpringBoot(2):generatorSpringBoot(3):docker部署...
设计模式是在大量的实践中总结和理论化之后优化迭代的代码结构、编程风格、以及解决问题的思考方式,目前共有23中设计模式。 1、Singleton单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 1)解决...
工厂模式和单例模式(https://www.jb51.net/article/184230.htm)应该是设计模式中应用最多的模式了,工厂模式的定义:提供创建对象的接口(来自百度百科:http://baike.baidu.com/view/1306799.htm),意思就是根据...
常用设计模式 单例模式 , 工厂模式 , 装饰者模式 , 代理模式 ... Java基础核心 JVM , 集合 , 类型 ,关键字... Java高级特性 多线程、锁、并发 框架 Spring , Mybatis , SpringBoot , SpringMVC ... 中间件 RPC , MQ...
\contentsline {chapter}{Contents}{2}{section*.1} {1}Java基础}{17}{chapter.1} {1.1}基本语法}{17}{section.1.1} {1.2}数字表达方式}{17}{... {16}Web基础}{215}{chapter.16} {16.1}HTML}{215}{section.16.1} {...
jdbc深入细致的讲解。主要讲解了sql注入。工厂模式的设计。单例模式的设计。以及各种数据库常见sql语句在java面向对象中的编写