黑马程序员技术交流社区

标题: 单例的延迟加载在多线程里的体现? [打印本页]

作者: 刘海源    时间: 2012-7-21 18:21
标题: 单例的延迟加载在多线程里的体现?
要具体代码和解析
作者: 郭凯敏    时间: 2012-7-22 03:42
本帖最后由 郭凯敏 于 2012-7-22 04:33 编辑

首先,单例设计模式分为懒汉和饿汉,懒汉模式由于为了节省资源等,当需要对象时才生成,但是这样会带来线程安全问题,以下是我的代码:
总体的意思是:当线程一刚进入 singleton() 方法,该线程判断完为空后,CPU跳到第二个线程,这时候由于第一个线程还没有生成对象(休眠中),第二个线程也成功判断并且产生了对象;然后CPU又自动调节回到第一个线程,第一个已经在该方法中,且还是按照之前判断的也就是认为st是null,他同样产生一个新的对象;由于new了2个新的对象,所以自然是不同的,我用compare())(自定义的方法)去测试两个值是否相等,结果有时等有时不等(CPU的调节是不规律的,有时候很理想,有时候你懂的...),当不想等时自然违背了单例的初衷,也就产生了安全问题

其实也好解决,加同步就OK,这个地方public static SingleTonLH singleton()写成public static synchronized SingleTonLH singleton()就可以了,只是效率不咋地了
  if (st == null) {
   st=new SingleTonLH();
  }
  return st;
}
}
public class SingleTonLhanTest {
public static void main(String[] args) throws Exception  {
  TestDemo1 test1=new TestDemo1();
  TestDemo2 test2=new TestDemo2();
   Thread t1=new Thread(test1);
   Thread t2=new Thread(test2);
   t1.start();
   System.out.println(compare());
   t2.start();
   System.out.println(compare());
}
public static boolean compare() throws Exception
{
  return TestDemo1.test()==TestDemo2.test();
}
}
//---------------------------------------------------------------------------------
class SingleTonLH {
private static SingleTonLH st;
private SingleTonLH() {
}
public static SingleTonLH singleton() throws InterruptedException {
  if (st == null) {
   st=new SingleTonLH();
  }
  return st;
}
}
//---------------------------------------------------------------------------------
class TestDemo1 implements Runnable {
public static SingleTonLH test() throws Exception
{
  SingleTonLH  st= SingleTonLH.singleton();
  return st;
}
public void run() {
  try {
   test();
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
}
}
//---------------------------------------------------------------------------------
class TestDemo2 implements Runnable {
public static SingleTonLH test() throws Exception
{
  SingleTonLH  st1= SingleTonLH.singleton();
  return st1;
}
public void run() {
  try {
   test();
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
}
}


作者: 袁野    时间: 2012-7-22 12:04
懒汉式!做俩次判断 效率能好很多




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2