请为什么这个双检测单例对象不行

run_mei 2004-06-14 05:31:14
在<<Java 与设计模式>>一书中说双检测单例对象在java中是不行的,原码如下
public MySingleton
{
finl static private MySingleton instance_ = null;
private MySingleton()
{
}
public MySingleton instance()
{
if( instance_ != null )
return instance_;
// 进入同步( 刚学同步关键词忘了 )
synchronized(this)
{
if( instance_ != null )
return instance_;
instance_ = new MySingleton();
return instance_;
}
}
}
书中的解释是在instance_ = new MySingleton();一句的执行顺序不一致,我对这一句话的解理是在这一句中会做下面几件事情
1 先在堆上new一块内存
2 调用MySingleton的构造函数
3 将生成的对象引用赋给instance_
双检测单例对象在java中是不行是因为2,3的执行顺序不能确定。
如果我的理解没错的话,那么人为的介入它的执行顺序,保证的它的执行顺序的话,就没有问题了。
将 instance_ = new MySingleton();
一句改为
MySingleton Tmp_instance = new MySingleton();
instance_ = Tmp_instance;
不就行了吗?
本人一直用c++,刚学java不久,有什么不对的地方请指出来。
...全文
68 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xxben 2004-09-02
  • 打赏
  • 举报
回复
gz
run_mei 2004-06-23
  • 打赏
  • 举报
回复
to fanlord(Leo)
谢谢你指出我的两个错
1.public MySingleton中间少了class关键字
2.finl static private MySingleton instance_ = null;
第三个问题我不明白
3.没有改变,因为java默认是用引用的,所以上面的代码改后和没该是没有区别的。
在c++中引用不可重新赋值的,在java中也一样吗

to shuneng
我加了synchronized呀


我改正后如下
public class MySingleton
{
static private MySingleton instance_ = null;
private MySingleton()
{
}
static public MySingleton instance()
{
if( instance_ != null )
return instance_;
// 进入同步( 刚学同步关键词忘了 )
synchronized( anyobject )
{
if( instance_ != null )
return instance_;
instance_ = new MySingleton();
return instance_;
}
}

public void print()
{
System.out.println("Hello World!");
}
public static void main(String[] args)
{
MySingleton.instance().print();
}
}

shuneng 2004-06-14
  • 打赏
  • 举报
回复
应为 public static MySingleton instance()
因为对象在抽象上是并行的,因此主要考虑是new运算可能有两个对象同时调用,
这里是有两个同时调用public static MySingleton instance()中的new,则可能
存在一个申请了堆空间而另一个又再申请,则会出现多余的申请。你可以试试对程序
作个标号,再排排序来看,可能会比较好理解。
fanlord 2004-06-14
  • 打赏
  • 举报
回复
程序有问题:
1.public MySingleton中间少了class关键字
2.finl static private MySingleton instance_ = null;
应为final,而且,final关键字使得无法对instance_再赋值,故instance_ = new MySingleton();显然错误,去掉final/
3.好像没有提供static的函数或者public的构造函数,无法实例化的

你在上面说的
将 instance_ = new MySingleton();
一句改为
MySingleton Tmp_instance = new MySingleton();
instance_ = Tmp_instance;
没有改变,因为java默认是用引用的,所以上面的代码改后和没该是没有区别的。

62,623

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧