Java设计模式之单例模式
来源:互联网 发布:360软件小助手独立 编辑:程序博客网 时间:2024/05/29 12:00
设计模式 - 单例模式
确保一个类最多有一个实例,并提供一个全局访问点 有些对象我们只需要一个:线程池、缓存、硬件设备等。 如果多个实例会有造成冲突、结果的不一致性等问题。 实现例子:静态变量 、全局变量
代码如下:
Instance.java
package com.lxf.singleton;/** * @address BeiJing * @author LiXufei * 单例 */public class Instance { //将构造私有化 防止外部直接实例化 private Instance(){} //准备变量 private static Instance mInstance; //判断创建 //同步锁概念?下文会提到 public static synchronized Instance getInstance(){ if (mInstance == null) { synchronized (Instance.class) { if (mInstance == null) { mInstance = new Instance(); } } } return mInstance; }}
Test.java
package com.lxf.singleton;/** * @address BeiJing * @author LiXufei * 测试类 */public class Test { public static void main(String[] args) { //创建多个对象判断是否为同一个实例 Instance s1 = Instance.getInstance(); Instance s2 = Instance.getInstance(); System.out.println(s1 instanceof Instance); System.out.println(s2 instanceof Instance); if (s1 == s2) { System.out.println("是同一个实例"); } }}
运行结果:
truetrue是同一个实例
说明:双锁机制的出现是为了解决前面同步问题和性能问题,看上面的代码,简单分析下确实是解决了多线程并行进来不会出现重复new对象,而且也实现了懒加载,但是当我们静下来并结合java虚拟机的类加载过程我们就会发现问题出来了,对于JVM加载类过程不熟悉的,这里我简单介绍下,熟悉的跳过这段(当然,既然你熟悉就自然会知道双锁的弊端了)。
jvm加载一个类大体分为三个步骤:
加载阶段:就是在硬盘上寻找java文件对应的class文件,并将class文件中的二进制数据加载到内存中,将其放在运行期数据区的方法区中去,然后在堆区创建一个java.lang.Class对象,用来封装在方法区内的数据结构; 连接阶段:这个阶段分为三个步骤,步骤一:验证,验证什么呢?当然是验证这个class文件里面的二进制数据是否符合java规范咯;步骤二:准备,为该类的静态变量分配内存空间,并将变量赋一个默认值,比如int的默认值为0;步骤三:解析,这个阶段就不好解释了,将符号引用转化为直接引用,涉及到指针,这里不做多的解释; 初始化阶段:当我们主动调用该类的时候,将该类的变量赋于正确的值(这里不要和第二阶段的准备混淆了),举个例子说明下两个区别,比如一个类里有private static int i = 5; 这个静态变量在"准备"阶段会被分配一个内存空间并且被赋予一个默认值0,当道到初始化阶段的时候会将这个变量赋予正确的值即5,了解了吧!
好了,上面大体介绍了jvm类加载过程,回到我们的双锁机制上来分析下问题出在了哪里?假如有两个并发线程a、b,a线程主动调用了静态方法getInstance(),这时开始加载和初始化该类的静态变量,b线程调用getInstance()并等待获得同步锁,当a线程初始化对象过程中,到了第二阶段即连接阶段的准备步骤时,静态变量doubleKey 被赋予了一个默认值,但是这时还没有进行初始化,这时当a线程释放锁后,b线程判断doubleKey != null,则直接返回了一个没有初始化的doubleKey 对象,问题就出现在这里了,b线程拿到的是一个被赋予了默认值但是未初始化的对象,刚刚可以通过锁的检索!
1 0
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- Activity生命周期执行顺序
- Javascript笔记——什么是Javascript
- 7.消息传递
- 2016年6月10号
- 【CSS笔记三】CSS选择器
- Java设计模式之单例模式
- 常用UML类图总结
- 一张图带你彻底了解二阶贝塞尔曲线
- JPA的基本运用
- MAC下配置环境变量
- nanopi spi oled不亮屏问题解决
- leetcode最后一遍
- Shell重定向&>file、2>&1、1>&2的区别
- git创建与管理远程分支