java设计模式之-----单例设计模式
来源:互联网 发布:python gnu readline 编辑:程序博客网 时间:2024/06/16 07:59
1.定义
单例设计模式:顾名思义,一个类只能产生一个实例,也就是说一个类只能有一个对象。就像古代的皇帝一样,只能有一个,多一个也不可以,这就是单例设计模式。
2.步骤及要点(注意)
- 私有化构造函数
- 提供一个本类的实例
- 提供一个对外的供外界访问的方法
实现过程
- 最简单的单例模式
(1)恶汉式
public class SingelInstance { // 私有化构造函数 private SingelInstance() { } // 产生一个实例对象 private static SingelInstance singleInstance = new SingelInstance(); // 提供一个供外界访问的方法 public static SingelInstance getInstance() { return singleInstance; }}
(2)懒汉式
public class SingelInstance1 { private SingelInstance1() { } private static SingelInstance1 singelInstance1; public static SingelInstance1 getSingelInstance1() { //假如同步关键字 synchronized (SingelInstance1.class) { if(singelInstance1 == null){ singelInstance1 = new SingelInstance1(); } } return singelInstance1; }}
比较: 恶汉式与懒汉式的区别仅在于先 new 与后 new 的问题,从名字就可以看出.懒汉式可以在需要的时候再new 对象,而恶汉式则是不管什么先 new 了一个对象.懒汉式的get 方法中要注意多线程的同步问题.为什么?java中new 一个对象不是简单的一个new 就能 new 出来的,只是我们自己这么觉得,其实,在编译后的执行的步奏中要经过几部才能产生出一个对象,假如不加入同步,就可能多个线程进入get 方法中产生多个对象.
注意: synchronized 关键字中不能用this关键字,为什么? 因为这个方法是静态的,静态优先于非静态,随着类的加载而加载,当对象还没产生时,静态方法就已经载入了,所以不能用this关键字,但是可以用类的class对象,原因前面已经说了.
(3)懒汉式(双重非空判断)
public class SingelInstance2 { private SingelInstance2() { } private static SingelInstance2 singelInstance2; public static SingelInstance2 getSingelInstance2() { //双重非空判断 if (singelInstance2 == null) { synchronized (SingelInstance1.class) { if (singelInstance2 == null) { singelInstance2 = new SingelInstance2(); } } } return singelInstance2; }}
为什么这样做: 在未加入双重非空判断的实例中,多个线程每次调用的get 方法中都要对对象上锁,事实上,只有在第一次创建的时候才需要对对象上锁,之后就不要了,因为对象已经new 出来了,之后只要直接返回就可以了,所以多加入一层非空判断有利于性能的提升.
分析: 假如现在有两个线程,A, B.
A,b线程同时进入了第一个if 判断,
A首先进入同步代码块,singelInstance2 为null,紧接着new 出了一个对象.由于jvm的优化机制,jvm给SingelInstance2 分配了存储空间,并复制给了成员变量singelInstance2 .(此时还没有实例化singelInstance2 ),然后A 离开了同步代码块.
此时B进入了同步代码块,由于此时singelInstance2 不为空,紧接着B出去了,并return 了singelInstance2.
此时B打算使用singelInstance2 ,但是singelInstance2 还没有实例化成对象,于是错误发生了.
(4) 静态内部类单例模式
public class SingelInstance3 { private SingelInstance3() { } private static class SingelInstanceFactory { private static SingelInstance3 singelInstance3 = new SingelInstance3(); } public SingelInstance3 getSingelInstance3() { return SingelInstanceFactory.singelInstance3; }}
为什么这样可以:
jvm内部机制能够保证一个类被加载的时候,这个类加载的过程式互斥的,这样当我们第一次调用getSingelInstance3
的时候,jvm能够保证singelInstance3
只被创建一次,并且会保证把赋值给singelInstance3内存空间初始化完毕,这样我们就解决了刚才的问题,同时该方法也只会在第一次调用的时候使用互斥机制,同时也解决了性能上的问题.
- java设计模式之单例设计
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- Java模式设计之单例模式
- Java模式设计之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java设计模式之单例模式
- Java模式设计之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- java设计模式之单例模式
- 不稳定排序之选择、快速、希尔以及堆排序
- Win7运行httpd.exe -> ApacheCould not reliably determine the server's fully qualified do main name
- 的境百屯毡姓送屯宜汲荒葡底尉鬃
- 传智播客javase总结 9
- java中的内部类汇总
- java设计模式之-----单例设计模式
- 什么是阻抗?什么是阻抗匹配?为什么要阻抗匹配?
- URL类方法源码解读
- 98 Consider the following scenario for your database: - Backup optimization is enabled in RMAN. - Th
- 第十二周--数据结构--图 算法库
- Android内存和进程的关系
- 在C6455上移植NDK
- 内部排序-插入排序-二叉树排序法
- 南阳理工ACM1076--方案数量