`
20386053
  • 浏览: 432382 次
文章分类
社区版块
存档分类
最新评论

【设计模式】单例设计模式的N中Java实现方法

 
阅读更多

转载请注明出处:http://blog.csdn.net/ns_code/article/details/17359719

特点

单例模式的特点:

1、只能有一个实例;

2、必须自己创建自己的一个实例;

3、必须给所有其他对象提供这一实例。

饿汉式单例模式

也称为预先加载法,实现方式如下:

class Single 
{
	private Single()(
		Syustem.out.println("ok");
	)
	private static Single instance = new Single();

	public static Single getInstance(){
		return instance;
	}
}

优点:线程安全,调用时反应速度快,在类加载的同时已经创建好了一个静态对象;

缺点:资源利用效率不高,可能该实例并不需要,但也被系统加载了

懒汉式单例模式

也称为延迟加载法,实现方式如下:

public class LazySingleton {
    private static LazySingleton instance;    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {             
		if (instance == null) {                       
			instance = new LazySingleton();           
		}
        return instance;                                      
    }
}

延迟加载法在适用于单线程环境,它不是线程安全的,引入多线程时,就必须通过同步来保护getInstance()方法,否则可能会返回LazySingleton的两个不同实例。比如,一个线程在判断instance为null后,还没来得及创建新的instance,另一个线程此时也判断到instance为null,这样两个线程便会创建两个LazySingleton实例。

可以将getInstance()方法改为同步方法,这样便可以避免上述问题,改进后的单例模式实现如下:

public class LazySingleton {
    private static LazySingleton instance;    
    private LazySingleton() {}
    
    public static synchronized LazySingleton getInstance() {             
		if (instance == null) {                       
			instance = new LazySingleton();           
		}
        return instance;                                      
    }
}

优点:资源利用率高,不执行getInstance就不会被实例。

缺点:第一次加载时反应不快,多线程使用不必要的同步开销大

这里的缺点主要是:每次调用getInstance()方法时,都要同步,而且很多时候的同步是没必要的,这将会极大地拖垮性能(尤其在需要多次调用getInstance方法的地方)。

DCL单例模式

针对延迟加载法的同步实现所产生的性能低的问题,我们可以采用DCL,即双重检查加锁(Double Check Lock)的方法来避免每次调用getInstance()方法时都同步。实现方式如下:

public class LazySingleton {
    private static LazySingleton instance;    
    private LazySingleton() {}
    
    public static LazySingleton getInstance() {             
		if (instance == null) {  
			synchronized(LazySingleton.class){
				if(instance == null){
					instance = new LazySingleton();  
				}
			}
		}
        return instance;                                      
    }
}

优点:资源利用率高,不执行getInstance就不会被实例,多线程下效率高。

缺点:第一次加载时反应不快,由于java 内存模型一些原因偶尔会失败,在高并发环境下也有一定的缺陷,虽然发生概率很小。

static内部类单例模式

该方法是为了解决DCL方法在并发环境中的缺陷而提出的,关于DCL在并发编程中存在的问题可以参考这篇文章:http://blog.csdn.net/ns_code/article/details/17348313的后半部分,其实现方式如下:

class Single 
{
	private Single()(
		Syustem.out.println("ok");
	)
	
	private static class InstanceHolder{
		private static final Singlet instance = new Single();
	}

	public static Single getInstance(){
		return InstanceHolder.instance;
	}
}

优点:线程安全,资源利用率高,不执行getInstance就不会被实例。

缺点:第一次加载时反应不快。

这里针对最后一种方法补充以下基本知识点:类级内部类(有static修饰的成员内部类)相当于其外部类的成员,只有在第一次使用时才会被装载,而不会在类加载器加载其外部类的时候被装载,而且只会被加载一次。因此,资源利用率高。

总结:在Java中由于会涉及到并发编程,考虑到效率、安全性等问题,一般常用饿汉式单例模式或static内部类单例模式,二者优缺点刚好颠倒过来,因此要根据具体情况来使用。

参考资料:http://blog.csdn.net/ns_code/article/details/17348313

http://write.blog.csdn.net/postlist/0/all/draft

http://www.myexception.cn/software-architecture-design/1235112.html

http://m.blog.csdn.net/blog/codezjx/8883599

http://blog.sina.com.cn/s/blog_6d2890600101gb8x.html

分享到:
评论

相关推荐

    java23种设计模式

    java23种设计模式,每一种模式都有详细的讲解,很全面,如果你想深入了解一下java23种设计模式,这会非常适合你的哦!上传乃为百度云连接,失效请留言。 内容: 001策略模式! N. B8 ~' D! f9 j+ g0 I 002观察者模式 ...

    Java面试宝典(设计模式,算法,Linux篇).docx

    2.单例设计模式 答: 单例模式有以下特点:  1、单例类只能有一个实例。  2、单例类必须自己创建自己的唯一实例。  3、单例类必须给所有其他对象提供这一实例。 懒汉式 和 饿汉式 3.介绍一下简单工厂模式 答: 简单...

    设计模式实验-Java代码类资源

    实现单例模式,组合模式,Builder模式,装饰器模式,并使用设计模式实现赌场

    二十三种设计模式【PDF版】

    设计模式之 Singleton(单态/单件) 阎宏博士讲解:单例(Singleton)模式 保证一个类只有一个实例,并提供一个访问它的全局访问点 设计模式之 Factory(工厂方法和抽象工厂) 使用工厂模式就象使用 new 一样频繁. ...

    Java面试 Java超级经典100问题 Java高级开发工程师必备 Java面试宝典

    单例设计模式.3.二维数组中查找目标值、4.替换字符串中的空格。5.从尾到头打印链表.6.由前序和中序遍历重建二叉树.7.用两个栈实现队列8.求旋转数组的最小数字、9.斐波那契数列的第n项(青蛙跳台阶)10.二进制中1的个数...

    java 面试题 总结

    声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其...

    java面试题

    62. java中实现多态的机制是什么? 42 63. 垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收? 42 63.1. 判断该对象是否是时候可以收集方法 43 63.1.1. 引用计数 ...

    完整学习笔记:《剑指offer》Java版代码实现

    第二题 单例设计模式 测试2 第三题 二维码中找到目标值 测试3 第四题 替换字符串中的空格 测试4 第五题 从尾到头打印链表 测试5 第六题 由前序和中序重建重建二叉树 测试6 第七题 使用两个栈实现队列 测试7 第八题 ...

    超级有影响力霸气的Java面试题大全文档

     声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,...

    java范例开发大全源代码

     8.3 面向对象的设计模式 241  实例156 Singleton单例模式 242  实例157 招聘(简单工厂模式) 243  实例158 同学聚会(工厂方法模式) 244  实例159 图书展(抽象工厂模式) 246  实例160 汽车...

    java范例开发大全

    实例213 二分查找法的实现方法 377 实例214 模拟操作系统的进程调度 379 实例215 利用栈将字符串逆序输出 381 实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的...

    Java范例开发大全 (源程序)

     实例213 二分查找法的实现方法 377  实例214 模拟操作系统的进程调度 379  实例215 利用栈将字符串逆序输出 381  实例216 动态的数组链表 382  实例217 你能猜出鱼是谁的宠物吗? 387  实例218 使用...

    Java范例开发大全(全书源程序)

    实例213 二分查找法的实现方法 377 实例214 模拟操作系统的进程调度 379 实例215 利用栈将字符串逆序输出 381 实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对...

    java范例开发大全(pdf&源码)

    实例213 二分查找法的实现方法 377 实例214 模拟操作系统的进程调度 379 实例215 利用栈将字符串逆序输出 381 实例216 动态的数组链表 382 实例217 你能猜出鱼是谁的宠物吗? 387 实例218 使用Collections类对List的...

    汉诺塔java源码-Towers-of-Hanoi:河内塔拼图项目

    它实现了单例设计模式。 你可以在文档部分的 src 代码中检查它的能力。 参考: TowersOfHanoi.java : 它实现了解决河内塔难题的主要逻辑。 它使用 的静态成员来显示结果。 要获取应用程序,请访问:

    validnumberleetcode自动机-coderjia-to-architect:JiA同学的代码人生,各种优秀语言、框架、中间件、神

    设计模式 面向对象设计原则 开闭原则 里氏替换原则 依赖倒置原则 单一职责原则 接口隔离原则 迪米特法则 合成复用原则 创建模式 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模式 结构模式 适配器模式 装饰...

    report 开源的访问层中间件,基于java平台

    report项目请求通道采用责任链模式设计,扩展性极强,流程完全可控! ankang-report report 是一个开源的访问层框架,基于java平台,依赖于spring,以Mozilla Public License 2.0 协议发布。可用于接口的调试及性能...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    昆山工业技术研究院着眼于为委托用户和质检机构搭建良好的沟通桥梁,免去目前市场业务中企业用户需要实地地并频繁地与检测机构沟通,从而提出自己的委托乃至下委托单、等待检测报告等,设计并研发了市场上首款提供...

    javalruleetcode-interview-question-collection:面试问题收集

    编程实现单例模式,懒汉和饱汉写法 操作系统 操作系统为什么要分内核态和用户态 为什么要有page cache,操作系统怎么设计的page cache 对文件系统的了解 计算机网络 get,post的区别 http请求的组成 https的原理 tcp...

    leetcode下载-LeetCode-Nowcoder-DataStruct:记录日常刷题与数据结构

    这个包下面的东西都是与并发编程相关的东西,比如阻塞队列实现生产者消费者模型,CAS,n种单例模式,线程交替打印,线程通信,读写锁,信号量,countdLaunch,circleBarrier等等 五. LeetCode 记录力扣刷题 由于本人不经常在...

Global site tag (gtag.js) - Google Analytics