达内培训:Java中的模式--单态

单态定义:

Singleton 模式主要作用是保证在Java 培训应用程序中,一个类Class 只有一个实例存在。

Singleton 模式就为我们提供了这样实现的可能。使用Singleton 的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java 垃圾回收(garbage collection)。

使用Singleton 注意事项:

有时在某些情况下,使用Singleton 并不能达到Singleton 的目的,如有多个Singleton 对象同时被不同的类装入器装载; 在EJB 这样的分布式系统中使用也要注意这种情况,因为EJB 是跨服务器,跨JVM 的

单态模式的演化:

单态模式是个简单的模式,但是这个简单的模式也有很多复杂的东西。

一,首先最简单的单态模式,单态模式1

import java.util.*;

class Singleton

{

private static Singleton instance;

private Vector v;

private boolean inUse;

private Singleton()

{

v = new Vector();

v.addElement(new Object());

inUse = true;

}

public static Singleton getInstance()

{

if (instance == null) //1

instance = new Singleton(); //2

return instance; //3

}

}

这个单态模式是不安全的,为什么说呢 ?因为没考虑多线程,如下情况

Thread 1 调用getInstance() 方法,并且判断instance 是null ,然後进入if 模块, 在实例化instance 之前,

Thread 2抢占了Thread 1的cpu

Thread 2 调用getInstance() 方法,并且判断instance 是null ,然後进入if 模块, Thread 2 实例化instance 完成,返回

Thread 1 再次实例化instance

这个单态已经不在是单态

二,为了解决刚才的问题:单态模式2

public static synchronized Singleton getInstance()

{

if (instance == null) //1

instance = new Singleton(); //2

return instance; //3

}

采用同步来解决,这种方式解决了问题,但是仔细分析正常的情况下只有第一次时候,进入对象的实例化,须要同步,其它时候都是直接返回已经实例化好的instance 不须要同步,大家都知到在一个多线程的程序中,如果同步的消耗是很大的,很容易造成瓶颈

三,为了解决上边的问题:单态模式3,加入同步

public static Singleton getInstance()

{

if (instance == null)

{

synchronized(Singleton.class) {

instance = new Singleton();

}

}

return instance;

}

同步改成块同步,而不使用函数同步,但是仔细分析,

又回到了模式一的状态,再多线程的时候根本没有解决问题

四,为了对应上边的问题:单态模式4,也就是很多人采用的Double-checked locking public static Singleton getInstance()

{

if (instance == null)

{

synchronized(Singleton.class) { //1

if (instance == null) //2

instance = new Singleton(); //3

}

}

return instance;

}

这样,模式一中提到的问题解决了。不会出现多次实例化的现象

当第一次进入的时候,保正实例化时候的单态, 在实例化后,多线程访问的时候直接返回,不须要进入同步模块,既实现了单态,又没有损失性能。表面上看我们的问题解决了,但是再仔细分析:

我们来假象这中情况:

Thread 1 :进入到//3位置,执行new Singleton(),但是在构造函数刚刚开始的时候被Thread2抢占cpu

Thread 2 :进入getInstance(),判断instance 不等于null, 返回instance , (instance已经被new ,已经分配了内存空间, 但是没有初始化数据)

Thread 2 :利用返回的instance 做某些操做,失败或者异常

Thread 1 :取得cpu 初始化完成

过程中可能有多个线程取到了没有完成的实例,并用这个实例作出某些操做。

-----------------------------------------

出现以上的问题是因为

mem = allocate(); //分配内存

instance = mem; //标记instance 非空

//未执行构造函数,thread 2从这里进入

ctorSingleton(instance); //执行构造函数

//返回instance

单态定义:

Singleton 模式主要作用是保证在Java 培训应用程序中,一个类Class 只有一个实例存在。

Singleton 模式就为我们提供了这样实现的可能。使用Singleton 的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java 垃圾回收(garbage collection)。

使用Singleton 注意事项:

有时在某些情况下,使用Singleton 并不能达到Singleton 的目的,如有多个Singleton 对象同时被不同的类装入器装载; 在EJB 这样的分布式系统中使用也要注意这种情况,因为EJB 是跨服务器,跨JVM 的

单态模式的演化:

单态模式是个简单的模式,但是这个简单的模式也有很多复杂的东西。

一,首先最简单的单态模式,单态模式1

import java.util.*;

class Singleton

{

private static Singleton instance;

private Vector v;

private boolean inUse;

private Singleton()

{

v = new Vector();

v.addElement(new Object());

inUse = true;

}

public static Singleton getInstance()

{

if (instance == null) //1

instance = new Singleton(); //2

return instance; //3

}

}

这个单态模式是不安全的,为什么说呢 ?因为没考虑多线程,如下情况

Thread 1 调用getInstance() 方法,并且判断instance 是null ,然後进入if 模块, 在实例化instance 之前,

Thread 2抢占了Thread 1的cpu

Thread 2 调用getInstance() 方法,并且判断instance 是null ,然後进入if 模块, Thread 2 实例化instance 完成,返回

Thread 1 再次实例化instance

这个单态已经不在是单态

二,为了解决刚才的问题:单态模式2

public static synchronized Singleton getInstance()

{

if (instance == null) //1

instance = new Singleton(); //2

return instance; //3

}

采用同步来解决,这种方式解决了问题,但是仔细分析正常的情况下只有第一次时候,进入对象的实例化,须要同步,其它时候都是直接返回已经实例化好的instance 不须要同步,大家都知到在一个多线程的程序中,如果同步的消耗是很大的,很容易造成瓶颈

三,为了解决上边的问题:单态模式3,加入同步

public static Singleton getInstance()

{

if (instance == null)

{

synchronized(Singleton.class) {

instance = new Singleton();

}

}

return instance;

}

同步改成块同步,而不使用函数同步,但是仔细分析,

又回到了模式一的状态,再多线程的时候根本没有解决问题

四,为了对应上边的问题:单态模式4,也就是很多人采用的Double-checked locking public static Singleton getInstance()

{

if (instance == null)

{

synchronized(Singleton.class) { //1

if (instance == null) //2

instance = new Singleton(); //3

}

}

return instance;

}

这样,模式一中提到的问题解决了。不会出现多次实例化的现象

当第一次进入的时候,保正实例化时候的单态, 在实例化后,多线程访问的时候直接返回,不须要进入同步模块,既实现了单态,又没有损失性能。表面上看我们的问题解决了,但是再仔细分析:

我们来假象这中情况:

Thread 1 :进入到//3位置,执行new Singleton(),但是在构造函数刚刚开始的时候被Thread2抢占cpu

Thread 2 :进入getInstance(),判断instance 不等于null, 返回instance , (instance已经被new ,已经分配了内存空间, 但是没有初始化数据)

Thread 2 :利用返回的instance 做某些操做,失败或者异常

Thread 1 :取得cpu 初始化完成

过程中可能有多个线程取到了没有完成的实例,并用这个实例作出某些操做。

-----------------------------------------

出现以上的问题是因为

mem = allocate(); //分配内存

instance = mem; //标记instance 非空

//未执行构造函数,thread 2从这里进入

ctorSingleton(instance); //执行构造函数

//返回instance


相关文章

  • 山西大学商务学院2013届本科毕业生实习报告
  • 山 西 大 学 商 务 学 院 2013 届本科毕业生实习报告 学生姓名: 所属班级: 所在系部: 实习单位: 实习时间: XX 09 计科 GB4 班 信息学院 北京达内金桥科技有限公司 2012 年 7 月 至 2012 年 12 月 ...查看


  • 达内上市追问:13万学生得到了什么价值?
  • 达内上市追问:13万学生得到了什么价值? 2014年4月3日,抢在清明小长假之前,达内国际在美国纳斯达克正式挂牌交易,给沉寂多年的中概股,打上了一直强心剂,之后的4月9日,爱康国宾也成功登陆纳斯达克.作为今年首登纳斯达克的中国企业,也是中国 ...查看


  • IT企业实习报告
  • 学校代码:10128 本科认识实习报告 ( 姓名:赵冬阳 学号:[1**********]3 学院:理学院 系别:数学系 专业:信息与计算科学 班级:信息与计算科学10-1班 二○一三年七月 暑期认识实习报告 --接受精英训练,体验IT文化 ...查看


  • 达内实习报告
  • 实习报告 实习单位(地点):渥瑞达 实习时间:2011 年 4 月 实习指导教师:周奕 学生学号:0706034501 学生姓名:韩芳 ---------------------------------- 1.实习单位总体印象 通过一个星期 ...查看


  • 全国十大网络营销课程培训机构排行榜
  • 全国十大网络营销课程培训机构排行榜 互联网已经进入了web3.0时代了,千万家传统企业开始拥抱互联网+,就连习大大也亲自参加世界互联网大会了,随着网络营销开始火爆起来,网络营销人才的稀缺也让不少网络营销培训机构也变得热门. 下面我们就看一看 ...查看


  • Java员工管理系统实训报告
  • 实 习 报 告 年 级 大三 专 业 计算机科学与技术 学 号姓 名 实习时间 2016.8.8-2016.8.28 实习地点 三峡大学 一.实习目的 进一步了解java 开发的相关知识,掌握java 开发的基本技术,丰富java 开发的实 ...查看


  • 软件工程个人简历
  • 个 人 简 历 姓名: 性别: 出生年月:1 院校: 专业:软件工程 学历:本科 英语:通过CET4,有良好英语阅读能力 手机: Email: 2005.9-2009.7 计算机科学与技术 2010.03-2010.8 北京达内科技 C+E ...查看


  • 北大青鸟和达内哪家好
  • 北大青鸟和达内哪家好 这样的问题其实是比较普遍的问题,有时候就是我们学校老师也很难给一个大家都满意的答案,北大青鸟和达内哪家好?或许你不知道,但是我问你一个问题,你就真能回答我么?例如肯德基和麦当劳那个好?你能告诉我那个好吗?我相信你也不知 ...查看


  • 2016年职业教育行业深度分析报告
  • 2016年职业教育行业深度分析报告 目录索引 一.职业教育的发展空间:学历职业教育展望空间大,非学历职业教育子领域蓬勃发展 . 5 (一)学历职业教育+非学历职业教育,职业教育体系层级分明 . ....................... ...查看


热门内容