Java设计模式学习01——单例模式(转)
原地址:http://blog.csdn.net/xu__cg/article/details/70182988
Java单例模式是一种常见且较为简单的设计模式。单例模式,顾名思义一个类仅能有一个实例,并且向整个系统提供这一个实例。
单例模式的特点:
- 单例类仅能有一个实例。
- 单例类必须为自己创建实例。
- 单例类必须向外界提供获取实例的方法。
以下是几种实现方法
一、懒汉式单例(能够延时加载)
public class SingleTon {
private static SingleTon instance = null ;
private SingleTon(){
}
public static SingleTon getInstance(){
if(instance==null){
instance=new SingleTon();
}
return instance ;
}
}
通过是构造方法私有化使该类不能在外界实例化,只能通过public方法获取实例,从而保证实例唯一。
但是以上的代码是线程不安全的,多线程并发的情况下,SingleTon可能产生多个实例,可以通过以下方法对getInstance方法进行改进从而保证懒汉式单例线程安全。
1.在getInstance()方法上加上同步
public class SingleTon {
private static SingleTon instance = null ;
private SingleTon(){
}
//方法同步,调用效率低!
public static synchronized SingleTon getInstance(){
if(instance==null){
instance=new SingleTon();
}
return instance ;
}
}
2.静态内部类式
public class SingleTon {
private static class SingletonClassInstance {
private static final SingleTon instance=new SingleTon();
}
private SingleTon(){
}
//方法没有同步,调用效率高!
public static SingleTon getInstance(){
return SingletonClassInstance.instance ;
}
}
3.双重校验锁式
public class SingleTon {
private volatile static SingleTon instance ;
private SingleTon(){
}
public static SingleTon getInstance(){
if(instance==null){
synchronized(SingleTon.class ){
if(instance==null){
instance=new SingleTon();
}
}
}
return instance ;
}
}
二、饿汉式单例 (不能够延时加载)
public class SingleTon {
//类初始化时,立即加载这个对象,加载类时,天然的是线程安全的!
private static SingleTon instance=new SingleTon();
private SingleTon(){
}
//方法没有同步,调用效率高!
public static SingleTon getInstance(){
return instance ;
}
}
饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。
三、枚举式单例
public enum SingleTon {
//这个枚举元素,本身就是单例对象!
INSTANCE;
//添加自己需要的操作!
public void singletonOperation(){
}
}
枚举式单例是线程安全的,调用效率高,并且可以天然的防止反射和反序列化漏洞。
四、防止反射和反序列化
事实上,通过Java反射或反序列化能够获取构造方法为private的类实例,那么所有的单例都会失效。所以为了避免这种后果,需要采取相应措施。
/**
*懒汉式单例模式(如何防止反射和反序列化漏洞)
*
*/
public class SingleTon implements Serializable {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。
private static SingleTon instance ;
private SingleTon(){ //私有化构造器
if(instance!=null){
throw new RuntimeException(); //防止反射
}
}
//方法同步,调用效率低!
public static synchronized SingleTon getInstance(){
if(instance==null){
instance=new SingleTon();
}
return instance ;
}
//反序列化时,如果定义了readResolve()则直接返回此方法指定的对象。而不需要单独再创建新对象!
private Object readResolve() throws ObjectStreamException {
return instance ;
} }
五、如何选用单例模式实现方式
- 单例对象占用资源少,且不需要延时加载:枚举式 好于 饿汉式
- 单例对象占用资源大,且需要延时加载:静态内部类式 好于 一般懒汉式
Java设计模式学习01——单例模式(转)的更多相关文章
- Java设计模式学习记录-单例模式
前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式. 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个. 单例模式 ...
- Java设计模式学习资源汇总
本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...
- Java设计模式之《单例模式》及应用场景
摘要: 原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6510196.html 所谓单例,指的就是单实例,有且仅有一个类实例,这个单例不应该 ...
- Java设计模式学习记录-模板方法模式
前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...
- Java设计模式学习记录-状态模式
前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...
- Java设计模式学习记录-观察者模式
前言 观察者模式也是对象行为模式的一种,又叫做发表-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式. 咱们目前用的最多的就是各种MQ(Message Queue ...
- Java设计模式学习记录-备忘录模式
前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...
- Java设计模式学习记录-迭代器模式
前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...
- Java设计模式学习记录-解释器模式
前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...
随机推荐
- Codeforces 828C String Reconstruction【并查集巧妙运用】
LINK 题目大意 给你n个串和在原串中的出现位置,问原串 思路 直接跑肯定是GG 考虑怎么优化 因为保证有解,所以考虑过的点我们就不再考虑 用并查集维护当前每个点之后最早的没有被更新过的点 然后就做 ...
- hadoop入门手册2:hadoop【2.7.1】【多节点】集群配置【必知配置知识2】
问题导读 1.如何实现检测NodeManagers健康?2.配置ssh互信的作用是什么?3.启动.停止hdfs有哪些方式? 上篇: hadoop[2.7.1][多节点]集群配置[必知配置知识1]htt ...
- MyEclipse项目突然报错JavanotFindClassException
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/UP19910522/article/details/25985277 好好的项目.从SVN检出到本地 ...
- as3 阻止后续侦听器
public class Test1 extends Sprite { private var spr:Sprite; private var spr2:Sprite; public function ...
- python编程规范系列--建议08~18
本系列来自<编写高质量代码 改善python程序的91个建议>的读书笔记整理. 本章主要内容 建议8:利用assert语句来发现问题 建议9:数据交换值时不推荐使用中间交换变量 建议10 ...
- linux(centos)下安装ffmpeg
[备忘]windows环境下20行php代码搞定音频裁剪 上次我的这篇文章将了windows下web中如何操作ffmpeg的文章,这里则记录下linux(centos)下的安装 首先:我花了中午大概1 ...
- 框架(yii和thinkphp)中实例化php内置或者扩展中的对象问题
将php原生语句实例化SphinxClient对象移植到yii2框架中报错 原生语句中这样写: $s = new SphinxClient(); 框架中应该加入反斜杠,这样写: $s = new \S ...
- saiku迁移至mysql步骤
saiku数据库的表和用户默认创建是在启动项目的时候,通过初始化 saiku-beans.xml 中的 h2database 这个bean执行org.saiku.service.Database类的i ...
- Spring集成缓存
Want 上一篇简单服务端缓存API设计设计并实现了一套缓存API,适应不同的缓存产品,本文重点是基于Spring框架集成应用开发. 缓存集成 以普通Web应用开发常见的搭配Spring+Spring ...
- Appium+python自动化25-windows版appium_desktop_V1.7.1
appium_desktop_v1.2.6 1.appium_desktop在github上最新下载地址:releases/tag/v1.2.6 2.下载后傻瓜式安装,然后启动appium,这个界面跟 ...