A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 韩长征 中级黑马   /  2014-5-29 10:33  /  2143 人查看  /  10 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 韩长征 于 2014-6-2 17:23 编辑

上次看到有个同学问的一个问题,当时没解决,后来也找不到这个帖子了,于是再发帖问一下。
代码如下,如果只有一句代码,请问会产生安全问题吗?
  1. class Single{
  2.         private Single(){}
  3.         private static Single s = null;
  4.         public static Single getInstance(){
  5.                 //这算不算是,就只有一句代码啊?
  6.                 //此句代码只有一句,会产生安全问题吗?
  7.                 //多线程时,cpu怎样执行此代码?
  8.                 return (s==null)?new Single():s;
  9.         }
  10. }
复制代码


评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

10 个回复

倒序浏览
同求高手解答啊,我也蒙了
回复 使用道具 举报
刚学习  到这   在深点不会了  
回复 使用道具 举报
没人解答,大神快现身啊。
回复 使用道具 举报
本帖最后由 西门吹风 于 2014-5-30 22:54 编辑

今天刚好看这个视频
当A程序调用静态方法getInstance()时,之前并没有实例,s为null,但当A程序准备建立实例时,
CPU恰好暂停执行A程序,去执行一个B程序,而B程序也需要调用静态方法getInstance(),
之前A程序虽然已经调用过getInstance(),但此时cpu还没有新建实例,所以s仍为null,导致
B程序也能进来创建实例,最终会产生两个实例。
我不是大神,还没学到多线程,不知道理解对不对

回复 使用道具 举报
大家都在求大神,很有压力,我不是大神,路过,看一下。
首先,return语句有问题。所谓单例就是只有一个实例,而你这个表达式出来的结果,每次都会创建一次对象。
return (s==null)?new Single():s;
因为在return语句中,并没有把创建的对象赋给s,所以s永远都是null,这样一来,每次“s==null”的判断都是true,每次都返回一个new Single(),所以这并没有满足单例模式。将这个表达式改成下面这样,应该就可以了:
return (s==null)?(s=new Single()):s;
像我们初学者,我不建议用这种表达式,还是现按部就班的打好基础吧!
回复 使用道具 举报 1 0
我觉得不会产生线程安全问题,这里三目运算符在理解上可以当做是if  else语句,但是使用的时候就不是这样的,使用的时候是连贯的,也就是说在操作一个对象的时候其他的线程就没有机会操作这个对象,产生线程安全的条件之一就是两条以上的语句操作同一个对象,这里只有一句,如果你把这个三目运算符改为if else 就会产生线程安全问题,
例如
  1. if(s==null){
  2.                   Thread.sleep(1000);
  3.                   return (s=new Single());
  4.           }else{
  5.                   return s;
  6.           }
复制代码
回复 使用道具 举报
这正好不太明白进来看看
回复 使用道具 举报
最终执行的是多条汇编指令,而不是在代码里面的一行或者是两行。不要只看代码里面的的一行两行,这个是有线程安全问题的。就算是一个a+b,也会对应N条汇编语句,什么寄存器赋值,然后相加,再赋值什么的。
回复 使用道具 举报
:shutup:同意   luoanjade  说法....
回复 使用道具 举报
谢谢大家的参与,我搜索了一些关于单例的信息,没有这种方法。
return (s==null)?s=new Single():s;
此句代码应该是不安全的。具体如何我也不清楚。
不过我方发现了其他2种单例方式。欢迎大家继续讨论。
  1. //枚举方法
  2. public enum Singleton {  
  3.     INSTANCE;  
  4. }  
复制代码
  1. //静态内部类方式
  2. class Singleton {
  3.            private Singleton() { }
  4.            private static class SingletonHolder {
  5.               private final static Singleton INSTANCE = new Singleton();
  6.            }
  7.            public static Singleton getInstance() {
  8.               return SingletonHolder.INSTANCE;
  9.            }
  10. }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马