jdon 解惑授道,企业信息化解决之道
 

热点Tag: AOP cache DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Spring Struts

Jdon框架演示

JiveJdon3.0
源码下载

GoF设计模式

在线教程

社区精彩讨论












用两个锁解决单例模式的同步

作者:老老猿 发表时间:2005年01月14日 11:26 回复此消息回复

原贴网址: http://www.jdon.com/jivejdon/thread/18694.html

public class Singleton {

private static Singleton instance = null;

static int i = 0;
//建实例锁 锁命令: i++ ,所有线程都可以开锁就是: i-- 命令,
//开锁的可能需要重新锁上。只有有资格建立实例的不用重新锁,有资格建立实例的条件时第一个开锁

static int j = 0;
//监视器 当多个实例开锁时监视是否有最先开锁的

public static Singleton getInstance() {

if (instance == null && i == 0) {
//如果没有实例,并且线程被锁(就是没线程可以最先开锁)

i++;
//进门就关门
j++;
//开始监视


//“开锁-重锁” 循环过程。 最先开锁的线程可以不重锁以建实例
while (i == j) {
//循环 如果没有一个线程能最先开锁
//则此次过程失败,循环下去.

i--; //开锁

if (j == i + 1) {
//本线程最先开锁,可以不重锁
instance = new Singleton();
//建实例,不重锁
}
else {
//不是第一个开锁的,可能和其线程一起开锁,也可能落后其他线程

i++;
//重锁

}
}
}

while (instance == null) {
//已经有线程最先开锁 只是没建完实例。等待
try {
Thread.sleep(1);
}
catch (InterruptedException ex) {

}
}

return instance;

}
}

Re: 用两个锁解决单例模式的同步 发表: 2005年01月14日 15:49 回复
guyuanwuxin 发表文章: 17/ 注册时间: 2004年02月06日 10:26
无论你怎么通过变量来解决D-LOCK都是不对的,,,,,,

Re: 用两个锁解决单例模式的同步 发表: 2005年01月14日 16:38 回复
老老猿 发表文章: 5/ 注册时间: 2005年01月14日 11:25
我现在还看不出上面程序的毛病,但我相信死锁是绝对可以避免的.

Re: 用两个锁解决单例模式的同步 发表: 2005年01月14日 16:46 回复
老老猿 发表文章: 5/ 注册时间: 2005年01月14日 11:25
发现问题,

if (instance == null && i == 0) {
//如果没有实例,并且线程被锁(就是没线程可以最先开锁)

i++;
//进门就关门
j++;
//开始监视


//“开锁-重锁” 循环过程。 最先开锁的线程可以不重锁以建实例
while (i == j) {

i j 开始就可能不一样大小


Re: 用两个锁解决单例模式的同步 发表: 2005年01月14日 16:53 回复
老老猿 发表文章: 5/ 注册时间: 2005年01月14日 11:25

i++;
//进门就关门
j++;
//开始监视

while (i != j) {//保证i j 同步
try {
Thread.sleep(1);
}
catch (InterruptedException ex1) {
}
}


//“开锁-重锁” 循环过程。 最先开锁的线程可以不重锁以建实例
while (i == j)

Re: 用两个锁解决单例模式的同步 发表: 2005年01月15日 10:22 回复
老老猿 发表文章: 5/ 注册时间: 2005年01月14日 11:25
确实是不可能实现,我无法控制 在分配开始的时候不叫i增加.

Re: 用两个锁解决单例模式的同步 发表: 2005年01月28日 16:21 回复
xiaodaichong 发表文章: 3/ 注册时间: 2005年01月28日 16:19
徒劳

Re: 用两个锁解决单例模式的同步 发表: 2005年01月29日 01:36 回复
fanf 发表文章: 7/ 注册时间: 2004年11月24日 07:26
Seems to me there are 2 problems:
1. I don't think operations like "instance == null" and "i++" are atomic. I haven't read the Java spec though. 老老猿, are you sure if they are atomic?
2. Two different threads may keep different copies of "instance","i" and "j" in their local buffers. Those buffers are only guaranteed to be refreshed when the thread enters and leaves a synchronized block.

Re: 用两个锁解决单例模式的同步 发表: 2005年01月29日 14:07 回复
youngS 发表文章: 38/ 注册时间: 2004年03月26日 00:03
找找锁方面的理论看看吧。同步的关键是原子操作,i++/i--之类的操作并不是原子操作,所以这是不可行的。难道java里面没有提供同步锁?为什么要自己实现锁机制?

Re: 用两个锁解决单例模式的同步 发表: 2005年02月04日 22:25 回复
abayi 发表文章: 26/ 注册时间: 2004年03月24日 15:02
can this to use this code.

public class Singleton
{

private static Singleton singleton=null;
private static Object lock=new Object();
public static Singleton getInstance()
{
if(singleton==null)
{
synchronized(lock)
{
if(singleton==null)
{
singleton=new Singleton();
}
}
}
}
}

Re: 用两个锁解决单例模式的同步 发表: 2005年02月25日 11:03 回复
xiaolongii 发表文章: 3/ 注册时间: 2004年08月10日 16:04
关键synchronized这个关键字不单单有加锁的功能,
还有多线程之间通讯的作用,
也就是一个线程改变了数据以后,
另一个线程在同时可能还是只看到了老数据,
除非用了同步,所以自己来用int作同步很难实现,
而且也没必要吧。

Re: 用两个锁解决单例模式的同步 发表: 2005年03月20日 00:51 回复
Lada314 发表文章: 6/ 注册时间: 2005年03月19日 23:38
Sigleton最好不用与多线程

要用多线程的话,就用Double-Checked Locking

eg:

class A extends B{
private static A a;
private A(){
}
private synchronized static void doSync(){
if(a==null)
a=new A();
}
public static A getInstance(){
if(a==null)
doSync();
return a;
}
}

Re: 用两个锁解决单例模式的同步 发表: 2005年06月13日 12:43 回复
diudiu3721 发表文章: 2/ 注册时间: 2005年06月13日 12:40
你觉得这个怎样?
private static Singleton instance = new Singleton();
.....
public static final Singleton get.....{
...........
return Singleton;
}

线程安全?

这个主题共有 12 回复 / 1 页 [ ]
 
上一篇: @怎么O?(banq大哥忙呀) 下一篇: 单例用来做缓存行吗?
 
查询本论坛 最热门帖子
快速发表回复:
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 
联系我们 | 关于我们 | RSS订阅 | 广告联系 | 网站地图 | 设为首页
Copyright (C) 2002-2007 Jdon.com, All Rights Reserved 版权所有 上海解道计算机技术有限公司
沪ICP备05018152号 如有意见请与我们联系 Powered by JdonFramework