- 浏览: 58965 次
- 性别:
- 来自: 上海
最新评论
-
hesai_vip:
写的很不错! 果断收藏!
使用Open Flash Chart(OFC)制作图表(Struts2处理) -
EvanWei:
不知道你最后选了哪一个公司,我最近也在应聘Rovi
两个offer:rovi和凯捷中国,不知道如何选择
简单概括你的问题,如果初始化发生在释放锁之前不会有什么问题,如果初始化发生在释放锁之后就有可能有问题。
- if (instance == null) { //0
- synchronized (Singleton.class) {// 1
- if (instance == null) {// 2
- instance = new Singleton();// 3
- //这里是不是只有instance初始化完整,他才会返回?
- return instance;// 4
- }
- }
if (instance == null) { //0 synchronized (Singleton.class) {// 1 if (instance == null) {// 2 instance = new Singleton();// 3 //这里是不是只有instance初始化完整,他才会返回? return instance;// 4 } }
是不是就能解决问题?
第三步可以看作一个赋值语句,只不过是调用构造函数初始化在付值语句之后。另外一个线程得到锁后就看到当前的instence已经不是null了就直接返回了,这个时候有可能第一个线程初始化工作做了一半,或者没有做。这样后面的线程得到的对像就会有问题。我感觉是这样的。
还有new的时候它为什么不会初始化完整了才,释放锁?
照这样理解,我是不是也可以认为第二种,在new的时候,只初始化一半,就释放了锁,其他线程进来不是一样看到的instance也不是null,而照样返回一个不完整的实例?
- public class Singleton {
- private volatile static Singleton instance = null;
- private Singleton() {}
- public static Singleton getInstance() {
- if (instance == null) { //0
- synchronized (Singleton.class) {// 1
- if (instance == null) {// 2
- instance = new Singleton();// 3
- }
- } //4
- }
- return instance;
- }
- }
public class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if (instance == null) { //0 synchronized (Singleton.class) {// 1 if (instance == null) {// 2 instance = new Singleton();// 3 } } //4 } return instance; } }
看上面的代码如果线程一执行语句3因为JVM编译器的优化工作会在构造方法实例化对像之前从构造方法返回指向该对像的引用。此时并没有执行构造方法。
然后程序执行出4此时开始执行构造方法当执行到一半的时候线程的时间片到期,此时并没有完成,线程二在0处结束等待并开始执行发现instance不为空就返回了。
我这样说你能理解吗?
第三步可以看作一个赋值语句,只不过是调用构造函数初始化在付值语句之后。另外一个线程得到锁后就看到当前的instence已经不是null了就直接返回了,这个时候有可能第一个线程初始化工作做了一半,或者没有做。这样后面的线程得到的对像就会有问题。我感觉是这样的。
还有new的时候它为什么不会初始化完整了才,释放锁?
照这样理解,我是不是也可以认为第二种,在new的时候,只初始化一半,就释放了锁,其他线程进来不是一样看到的instance也不是null,而照样返回一个不完整的实例?
总之楼主总结的不错。能用的这几种方式都总结出来了。
第三步可以看作一个赋值语句,只不过是调用构造函数初始化在付值语句之后。另外一个线程得到锁后就看到当前的instence已经不是null了就直接返回了,这个时候有可能第一个线程初始化工作做了一半,或者没有做。这样后面的线程得到的对像就会有问题。我感觉是这样的。
这样的写法是能避免无序写入的问题。因为别的线程进入不了方法体,除非当前线程释放锁。这样就能确保实例化完成。我的理解对吗?
public class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
return instance;
}
}
正如你所说的用ThreadLocal能解决这个问题,担是我认为你的代码里面的写法是不是有问题。
public class Singleton {
private static final ThreadLocal perThreadInstance = new ThreadLocal();
private static Singleton singleton ;
private Singleton() {}
public static Singleton getInstance() {
if (perThreadInstance.get() == null){
// 每个线程第一次都会调用
createInstance();
}
return singleton;
}
private static final void createInstance() {
synchronized (Singleton.class) {
if (singleton == null){
singleton = new Singleton();
}
}
perThreadInstance.set(perThreadInstance);
}
}
倒数第三行perThreadInstance.set(perThreadInstance);应该写成perThreadInstance.set(singleton);
除此之外每一个线程都会有一个singleton的副本这样一样会造成资源浪费。本来单态模式就是想节省资源的,这样与模式的初衷不相符吧。
还有这种ThreadLocal方式的解决方案能不能应用在分布式情形,不同的JVM,ClassLoader?
我认为第二种方法同步方法加锁对像是this,而第三种加载方式是同步当前类的类对像。所以单从范围上面来讲只是if (instance == null)这一句的区别。
第二种加锁的对象不是this,其实也是 Singleton.class 锁对象,以前我测试过。为什么说是Singleton.class而不是this呢,最简单的理由就是该方法是静态的,这就很明显了:静态方法是不能访问this的。
其实第二也等同于下在面:
- public class Singleton {
- private volatile static Singleton instance = null;
- private Singleton() {}
- public static Singleton getInstance() {
- synchronized (Singleton.class) {
- if (instance == null) {
- instance = new Singleton();
- }
- }
- return instance;
- }
- }
public class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } return instance; } }
第二种与第三种唯一的区别就是第三种多了“instance == null”的条件,但该条件的检测不是放在同步块中的,正是因为这一点,导致了双重检测失效!
我认为第二种方法同步方法加锁对像是this,而第三种加载方式是同步当前类的类对像。所以单从范围上面来讲只是if (instance == null)这一句的区别。
发表评论
-
更深入的TOMCAT中文乱码解决之道,包括GET/POST(转)
2011-06-23 10:45 1605在tomcat5中发现了以前处 ... -
一些软件设计的原则
2011-06-20 15:20 908摘录自:http://coolshell.cn/article ... -
Jboss4集群配置
2011-06-08 17:49 35211.前言 2006年,Jboss公司被 ... -
ORACLE索引介绍与高性能SQL优化
2011-06-08 15:52 1023什么是索引 索引是建立在表的一列或多个列上的辅助对象,目 ... -
说说大型高并发高负载网站的系统架构(from tianya)
2011-06-07 15:03 913说说大型高并发高负载 ... -
dao对象不能使用注解@Repository实例化的情形之一
2011-06-03 17:47 15764项目中定义一个dao对象,继承了 JdbcDaoSupport ... -
SQL Server 索引结构及其使用(四)
2011-06-01 23:04 776聚集索引的重要性和如 ... -
SQL Server 索引结构及其使用(三)
2011-06-01 23:04 751实现小数据量和海量数据的通用分页显示存储过程 建立一个 W ... -
SQL Server 索引结构及其使用(二)
2011-06-01 23:03 863改善SQL语句 很多人 ... -
SQL Server 索引结构及其使用1
2011-06-01 22:59 852一、深入浅出理解索引结构 实际上,您可以把索引理解为一种特 ... -
如何使用Spring来管理Struts中的Action
2011-03-25 20:31 774当指定struts.objectFactory为spring时 ... -
eclipse无法启动JBoss5.1.0的解决小办法
2011-03-07 15:00 2024最近看看JBoss,发现早已有了新版本,好久没有关注了,于是下 ... -
log4j配置详解1
2010-12-17 15:15 776>>>>1. 概述Log4j ... -
Java日志系统框架的设计与实现
2010-12-17 11:15 1365在Java 领域,存在大量的日志组件,open-open收录了 ... -
胜负彩10001期欧洲四大博彩公司最新赔率
2010-09-20 13:37 24胜负彩对阵 威廉希尔 Interwetten 立博l ... -
明明白白Unsupported major.minor version 49.0的错误
2010-08-05 14:33 518转载自:http://www.blogjava.net/Unm ... -
一位系统分析师的工作经验总结
2010-07-20 15:39 1553谈到项目的需求分析,几乎每个软件开发人员 ... -
Tomcat6的结构
2010-05-17 17:28 1654本文分为三部分,分别为: Tomcat文件系统 Tom ... -
tomcat生命周期管理 LifeCycle
2010-05-17 15:12 1003Servlet规范中定义了一个Servlet的生命周期, To ... -
计算机端口管理
2010-05-12 11:03 923在运行中输入cmd,进入命令行,然后输入netstat -an ...
相关推荐
本示例包含三个经典的设计模式:单例模式、建造者模式和策略模式,它们都是面向对象设计的重要组成部分,尤其在C#编程中广泛应用。 ### 单例模式 单例模式确保一个类只有一个实例,并提供一个全局访问点。这种模式...
实现单例模式的方法有很多,如懒汉式、饿汉式、双重检查锁定等。以下是一个简单的双重检查锁定实现: ```java public class DataSourceSingleton { private static volatile DataSource instance; private ...
iphone 单例模式// Permission is given to use this source code file without charge in any // project, commercial or otherwise, entirely at your risk, with the condition // that any redistribution (in ...
设计模式 书中模式的例子都是基于java的 全书深入浅出 不仅讲明白了常用常用的设计模式...由于最多上传15M,全书分为3个part传输,将part1、part2、part3放在同一个文件夹中,同时选中,选择解压到当前目录即可。part2.
《Java与模式》是一部深入探讨Java编程语言与设计模式结合应用的著作,旨在帮助开发者提升软件设计能力,更好地理解和实践面向对象设计原则。这个压缩包包含的部分可能为书中的部分内容或者是一系列相关教程的章节,...
在这个"设计模式中文版part2"中,我们继续深入探讨Java编程语言中的设计模式。 1. **单例模式** (Singleton): 单例模式确保一个类只有一个实例,并提供全局访问点。在Java中,通常通过私有构造函数和静态工厂方法...
Java与模式.part2 Java与模式.part2 Java与模式.part2
《Java与模式》系列教程是深入理解Java编程和设计模式的重要资源,这部分涵盖了第...对于压缩包中的"Java与模式.part19-21"文件,建议按照章节顺序逐步学习,结合实际案例进行实践,以确保对每一个主题都有深入的理解。
《设计模式》中文版part2是一本深入探讨软件设计原则和最佳实践的书籍,它将经验丰富的程序员在解决常见问题时所采用的方法整理为可复用的解决方案。这本书的第二部分可能涵盖了23种经典的GoF设计模式,以及其他一些...
本电子书一共两个压缩文档,本文件为part2. 《研磨设计模式》完整覆盖GoF讲述的23个设计模式并加以细细研磨。初级内容从基本讲起,包括每个模式的定义、功能、思路、结构、基本实现、运行调用顺序、基本应用示例等,...
敏捷软件开发:原则、模式与实践.part2.rar 还有part1,别忘了下载哦.
第1章 模式的简史和形而上学 第2章 统一建模语言UML简介 第3章 软件的可维护性和可复用性 第4章 开闭原则 第5章 专题 JAVA语言的接口 第6章 专题 抽象类 第7章 里氏代换原则 ...第15章 单例模式 第16章 .......
本书是一部非常实用的CSS 与HTML(XHTML)解决方案手册。书中包含了350 多种可以立即使用的设计模式(涉及文本、背景、边框、图片、表格、布局等多方面),并介绍了每种模式的原理... 精通CSS与HTML设计模式.part11.rar
《Java与模式.part07-09.rar》这个压缩包文件很显然包含了关于Java编程语言和设计模式的深入探讨。这部分内容可能源自一本名为《Java与模式》的书籍或者是一系列教程材料。从文件名来看,它可能是该资料的第七到第九...
《设计模式》中文版part1是一本深入探讨软件设计模式的重要资源,对于提升开发者的设计能力和代码质量具有极大的价值。设计模式是经验丰富的软件开发人员在解决常见问题时所形成的通用解决方案,它们经过了时间和...
《Java与模式》系列教程是深入理解Java编程语言和设计模式的重要资料,涵盖了从基础到高级的Java技术以及各种常用...因此,对于想要在Java领域深入发展的程序员来说,《Java与模式》.part13-15的学习无疑是必不可少的。
研磨设计模式.part2 一定要下载5部分
这个压缩包分为多个部分,其中包括"Java与模式(清晰书签版).part2.rar",可能是由于文件大小限制或上传问题被分成了多个部分进行分享。用户在获取到所有部分后,需要将它们合并解压才能得到完整的资料。 设计模式是...
敏捷软件开发:原则、模式与实践.part2
Head First设计模式(中文版)Part0(封面_封底_序_前言目录).rar Head First设计模式(中文版)Part1(1-39页).rar Head First设计模式(中文版)Part2(39-107页).rar <br>据反映:上次上传的Part3(108-end).part...