- 浏览: 453114 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (211)
- java (37)
- spring相关 (3)
- struts (10)
- 面试 (1)
- jsp/servlet (18)
- 持久化框架 (1)
- IT相关新闻 (3)
- 服务器 (11)
- 插件 (4)
- pushlet (3)
- js (24)
- oracle (29)
- mysql (9)
- hibernate (5)
- 开发工具 (6)
- jquery (6)
- 页面标签jstl,el (1)
- linux (25)
- 英语 (1)
- log4j (1)
- html/css (6)
- sqlserver (2)
- dwr (1)
- 设计模式 (4)
- vmware (2)
- office (1)
- eclipse (5)
- svn (1)
- webservice (1)
最新评论
-
18335864773:
建议使用 pageoffice 组件套红
js操作word套红 -
lopez:
数据库系统的客户程序只要向数据库系统声明了一个事务,数据库系统 ...
Hibernate事物控制与管理 -
liujq4512:
删了还是没用
An internal error occurred during: "Initializing Java Tooling". -
elaine0111:
非常感谢这篇文章,嘿嘿,解决了我的问题。我把这段代码保存在我的 ...
Js设置文本框中焦点位置在最后 -
weishuguangeye:
不错!
单例模式(Singleton)
BestUpon 写道
首先我们先看看一个例子,在说什么是单利模式(Singleton):
package org.bestupon.dp.singleton;
/**
*
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:08:28
* @ask jdk中Runtime这个类似就是一个单例模式的应用:
*
* @answer
*/
public class Test4RunTime {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
runtime.freeMemory();
}
}
上面的例子可以看出在没有使用new,却获得了一个Runtime对象,这是为什么呢?让我们看看java.lang.Runtime.java的源码到底是怎么一回事:
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
// 以下略
}
以上是Runtime.java开头部分的代码,我们可以很清楚的看见,一开头就直接 new Runtime(), 一个对象,并且是静态的。在getRuntime()的时候,
直接将其返回给请求的客户端。 上面结构即采用Singleton模式设计,其结构使用 UML 描述如下所示:
Singleton的英文意义是独身,也就是只有一个人,应用在面向对象语言上,通常翻译作单例:单一个实例(Instance)。Singleton模式可以保证一个类别 只有一个实例,并只提供一个访问(visit)这个实例的方法。
1.定义:单例模式就是确保一个类中只有一个实例,并且该实例必须自动创建,并向整个系统提供该实例。
2.使用时机:当系统要求一个类只有一个实例时,就需要使用用单例模式。
有几个实例上面结构的方法,可以在第一次需要实例时再建立对象,也就是采用所谓的Lazy Initialization:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// .. 其它实例
}
上面的实例适用于单线程的程序,在多线程的程序下,以下的写法在多个线程的竞争资源下,将仍有可能产生两个以上的实例,例如下面的情况:
Thread1: if(instance == null) // true
Thread2: if(instance == null) // true
Thread1: instance = new Singleton(); // 产生一个实例
Thread2: instance = new Singleton(); // 又产生一个实例
Thread1: return instance; // 回传一个实例
Thread2: return instance; // 又回传一个实例
在多线程的环境下,为了避免资源同时竞争而导致如上产生多个实例的情况,加上同步(synchronized)机制:
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
synchronized static public Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
不过这种简单的写法不适合用于像服务器这种服务很多线程的程序上,同步机制会造成相当的效能低落,为了顾及Singleton、Lazy Initialization与效能问题,因而有了Double-check Locking的模式:
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if (instance == null){
synchronized(Singleton.class){
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
也就是只有在第一次建立实例时才会进入同步区,之后由于实例已建立,也就不用进入同步区进行锁定。Java中Runtime类别的作法简单的多, 它舍弃了Lazy Initialization,如果您要取得单例的机会不是很多,可以用这种方式:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// ....
}
public static Singleton getInstance() {
return instance;
}
// 其它实例
}
Singleton本身的观念简单但应用 很广,因而很多时候必须对实际环境作一些考虑与调整。
3.总结:
单例模式可以分为两种:饿汉式和懒汉式两种,饿汉是在系统启动的一开始就初始化好了实例,而懒汉式是在第一次访问的时候才初始化实例。
package org.bestupon.dp.singleton;
/**
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:34:27
* @ask 饿汉式单利模式
* @answer
*/
public class HungerSingleton {
/**
* 一开始就初始化好了实例
*/
private static HungerSingleton instance = new HungerSingleton();
private HungerSingleton() {
}
public static HungerSingleton getInstance() {
return instance;
}
}
package org.bestupon.dp.singleton;
/**
*
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:41:22
* @ask 懒汉式单例模式
* @answer
*/
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
4.优点:
在单利模式中,客户调用类的实例时,只能调用一个公共的接口,这就为整个开发团队提供了共享的概念,
5.缺点:
单利模式在实例化后,是不允许类的继承的;在分布式系统中,当系统的单利模式类被复制运行在多个虚拟机下时,在每一个虚拟机下都会创建一个实例对象,此时如果想知道具体哪个虚拟机下运行着单例对象是很困难的,而且单例类是很难实现序列化的。
更新(纠正)2010-6-17:
由于端午节放假的缘故,各位同仁在期间提出了很多的问题,也指出了我思维的局限性,没有及时的更新于回复各位好友的,深表遗憾!
针对单例模式的很多用法,前面一直是在所单一线程的问题,本来设计多线程的问题就很少,也对双重锁定这个问题没有深入的五挖掘,导致了犯了今天这样的错误。之后参考了一些资料,针对各位朋友提出的问题与我自身存在的问题,进行改进!参考的文章是:IBMDeveloperWorks(中国)的网站上的文章《双重检查锁定及单例模式》(http://www.ibm.com/developerworks/cn/java/j-dcl.html)。这篇文章真针对各种问题都有分析,包括可见性等问题。得出了一个结论:双重锁定失效的主要原因是:不同JVM之间的无序写入问题,多线程之间的独占、休眠(记忆复苏)所引起的不同不问题。
最终本文提出了一个建议:建议不要使用“双重锁定”!一个解决单例模式的方案:
底线就是:无论以何种形式,都不应使用双重检查锁定,因为您不能保证它在任何 JVM 实现上都能顺利运行。JSR-133 是有关内存模型寻址问题的,尽管如此,新的内存模型也不会支持双重检查锁定。因此,您有两种选择:
接受如清单 2 中所示的 getInstance() 方法的同步。
放弃同步,而使用一个 static 字段。
选择项 2 如清单 10 中所示:
/**
*使用 static 字段的单例实现
**/
class Singleton
{
private Vector v;
private boolean inUse;
private static Singleton instance = new Singleton();
private Singleton()
{
v = new Vector();
inUse = true;
//...
}
public static Singleton getInstance()
{
return instance;
}
}
再次感谢各位朋友的关注!
首先我们先看看一个例子,在说什么是单利模式(Singleton):
package org.bestupon.dp.singleton;
/**
*
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:08:28
* @ask jdk中Runtime这个类似就是一个单例模式的应用:
*
* @answer
*/
public class Test4RunTime {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
runtime.freeMemory();
}
}
上面的例子可以看出在没有使用new,却获得了一个Runtime对象,这是为什么呢?让我们看看java.lang.Runtime.java的源码到底是怎么一回事:
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {
return currentRuntime;
}
/** Don't let anyone else instantiate this class */
private Runtime() {}
// 以下略
}
以上是Runtime.java开头部分的代码,我们可以很清楚的看见,一开头就直接 new Runtime(), 一个对象,并且是静态的。在getRuntime()的时候,
直接将其返回给请求的客户端。 上面结构即采用Singleton模式设计,其结构使用 UML 描述如下所示:
Singleton的英文意义是独身,也就是只有一个人,应用在面向对象语言上,通常翻译作单例:单一个实例(Instance)。Singleton模式可以保证一个类别 只有一个实例,并只提供一个访问(visit)这个实例的方法。
1.定义:单例模式就是确保一个类中只有一个实例,并且该实例必须自动创建,并向整个系统提供该实例。
2.使用时机:当系统要求一个类只有一个实例时,就需要使用用单例模式。
有几个实例上面结构的方法,可以在第一次需要实例时再建立对象,也就是采用所谓的Lazy Initialization:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// .. 其它实例
}
上面的实例适用于单线程的程序,在多线程的程序下,以下的写法在多个线程的竞争资源下,将仍有可能产生两个以上的实例,例如下面的情况:
Thread1: if(instance == null) // true
Thread2: if(instance == null) // true
Thread1: instance = new Singleton(); // 产生一个实例
Thread2: instance = new Singleton(); // 又产生一个实例
Thread1: return instance; // 回传一个实例
Thread2: return instance; // 又回传一个实例
在多线程的环境下,为了避免资源同时竞争而导致如上产生多个实例的情况,加上同步(synchronized)机制:
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
synchronized static public Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
不过这种简单的写法不适合用于像服务器这种服务很多线程的程序上,同步机制会造成相当的效能低落,为了顾及Singleton、Lazy Initialization与效能问题,因而有了Double-check Locking的模式:
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if (instance == null){
synchronized(Singleton.class){
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
也就是只有在第一次建立实例时才会进入同步区,之后由于实例已建立,也就不用进入同步区进行锁定。Java中Runtime类别的作法简单的多, 它舍弃了Lazy Initialization,如果您要取得单例的机会不是很多,可以用这种方式:
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
// ....
}
public static Singleton getInstance() {
return instance;
}
// 其它实例
}
Singleton本身的观念简单但应用 很广,因而很多时候必须对实际环境作一些考虑与调整。
3.总结:
单例模式可以分为两种:饿汉式和懒汉式两种,饿汉是在系统启动的一开始就初始化好了实例,而懒汉式是在第一次访问的时候才初始化实例。
package org.bestupon.dp.singleton;
/**
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:34:27
* @ask 饿汉式单利模式
* @answer
*/
public class HungerSingleton {
/**
* 一开始就初始化好了实例
*/
private static HungerSingleton instance = new HungerSingleton();
private HungerSingleton() {
}
public static HungerSingleton getInstance() {
return instance;
}
}
package org.bestupon.dp.singleton;
/**
*
* @author BestUpon
* @email bestupon@foxmail.com
* @date 2010-6-13上午11:41:22
* @ask 懒汉式单例模式
* @answer
*/
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
}
4.优点:
在单利模式中,客户调用类的实例时,只能调用一个公共的接口,这就为整个开发团队提供了共享的概念,
5.缺点:
单利模式在实例化后,是不允许类的继承的;在分布式系统中,当系统的单利模式类被复制运行在多个虚拟机下时,在每一个虚拟机下都会创建一个实例对象,此时如果想知道具体哪个虚拟机下运行着单例对象是很困难的,而且单例类是很难实现序列化的。
更新(纠正)2010-6-17:
由于端午节放假的缘故,各位同仁在期间提出了很多的问题,也指出了我思维的局限性,没有及时的更新于回复各位好友的,深表遗憾!
针对单例模式的很多用法,前面一直是在所单一线程的问题,本来设计多线程的问题就很少,也对双重锁定这个问题没有深入的五挖掘,导致了犯了今天这样的错误。之后参考了一些资料,针对各位朋友提出的问题与我自身存在的问题,进行改进!参考的文章是:IBMDeveloperWorks(中国)的网站上的文章《双重检查锁定及单例模式》(http://www.ibm.com/developerworks/cn/java/j-dcl.html)。这篇文章真针对各种问题都有分析,包括可见性等问题。得出了一个结论:双重锁定失效的主要原因是:不同JVM之间的无序写入问题,多线程之间的独占、休眠(记忆复苏)所引起的不同不问题。
最终本文提出了一个建议:建议不要使用“双重锁定”!一个解决单例模式的方案:
底线就是:无论以何种形式,都不应使用双重检查锁定,因为您不能保证它在任何 JVM 实现上都能顺利运行。JSR-133 是有关内存模型寻址问题的,尽管如此,新的内存模型也不会支持双重检查锁定。因此,您有两种选择:
接受如清单 2 中所示的 getInstance() 方法的同步。
放弃同步,而使用一个 static 字段。
选择项 2 如清单 10 中所示:
/**
*使用 static 字段的单例实现
**/
class Singleton
{
private Vector v;
private boolean inUse;
private static Singleton instance = new Singleton();
private Singleton()
{
v = new Vector();
inUse = true;
//...
}
public static Singleton getInstance()
{
return instance;
}
}
再次感谢各位朋友的关注!
发表评论
-
java生成pdf以及解决中文中文乱码问题
2013-03-11 16:33 12406itext版本:5.4.0 下载 ... -
jax-ws webservice编程
2013-01-29 16:07 64731.理解JAX-WS 1.1JAX-WS概述 JAX ... -
was6.1修改java编译版本
2013-01-11 09:06 1942jsp中如果用到了jdk1.5的新特性,在was6.1下编译会 ... -
eclipse生成javadoc乱码解决方式
2013-01-11 09:05 843在Extra javadoc options下增加如下参数 j ... -
Eclipse Jee项目开发前准备 (转)
2012-12-31 09:06 997Eclipse Jee项目编码设置 Window-> ... -
SVN 签出源码 Struts Spring Hibernate
2011-09-15 09:38 1170SVN 签出源码 Struts Spring ... -
几种Java数据库连接池实现(一)
2011-08-31 14:15 1672几种Java数据库连接池实现(一) (一) package s ... -
win7下硬盘安装ubuntu
2011-08-22 20:36 990安装方法见附件 -
比较好的java网站[推荐]
2011-04-07 12:42 15831. The Source for Java Technol ... -
jad反编译jar文件
2011-02-15 16:56 1492//首先使用jar命令将jar文件解压缩到classes目录 ... -
接口与抽象类区别
2011-01-19 15:21 650接口与抽象类区别 《设计模式Java手册》中的,觉得写得很简 ... -
正则入门
2010-12-20 13:21 867< type="text/javascript ... -
序列键生成器与单例及多例模式
2010-12-13 10:37 1082在一个关系数据库中,所有的数据都是存储在表里,而每一个表都有一 ... -
Java中日期格式转换
2010-12-10 15:35 1499Java中日期格式转换 /** * 字符串转换为jav ... -
获取天气预报
2010-12-08 11:30 1019最近工作有用到web services,而这两天也比较有空,就 ... -
java解压缩zip包
2010-11-10 12:32 2100package test; import java.io.B ... -
项目中常见的错误
2010-09-27 08:47 75799项目中遇到的错误(c9bcf64c) sql错误 找不到 ... -
Java杂谈(十三)——ORM
2010-08-20 09:02 1115其实J2ee的规范指南 ... -
Java杂谈(十二)--JVM
2010-08-20 09:01 1030本来这次应该讲 ... -
Java杂谈(十一)--Spring
2010-08-20 09:01 890引用《Spring2.0技 ...
相关推荐
本系统的开发与设计是基于vue为前端页面核心框架为django/flask,技术方面主要采用了Html、Js、CSS3、python、Mysql。 本课题使用Python语言进行开发。代码层面的操作主要在PyCharm中进行,将系统所使用到的表以及数据存储到MySQL数据库中,方便对数据进行操作本课题基于WEB的开发平台 ②前端开发选择:Vue。 ②后端开发选择:python、django/flask。 ③数据库选择:MySQL。 ④开发工具选择:pycharm、Navicat for MySQL。 包含了我的信息、用户管理、期货公司管理、开户信息管理、充值信息管理、期货期货信息管理、期货投资管理、取消投资管理、投资风险管理、意见反馈、系统管理
springboot052基于Springboot+Vue旅游管理系统毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
计算机图形学之动画和模拟算法:Keyframe Animation:碰撞检测与响应.docx
行业研究报告、行业调查报告、研报
调用文心一言api的一个尝试
hertzbeat的docker镜像文件
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
项目经过测试均可完美运行! 环境说明: 开发语言:java jdk:jdk1.8 数据库:mysql 5.7+ 数据库工具:Navicat11+ 管理工具:maven 开发工具:idea/eclipse
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
计算机图形学之动画和模拟算法:Procedural Animation:物理基础:力与运动.docx
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
2112312312321321