黑马程序员技术交流社区
标题:
多线程中运用单例设计模式的小疑惑【求大神指点】
[打印本页]
作者:
何仕映
时间:
2013-3-20 09:07
标题:
多线程中运用单例设计模式的小疑惑【求大神指点】
本帖最后由 何仕映 于 2013-3-20 12:07 编辑
为什么加上下面注释的延时语句,多线程就不运行了呢?
求大神分析一下执行过程。
/*
将买票的小实例,在建立对象的时候通过单例设计模式保证对象的唯一性
*/
class Ticket implements Runnable
{
private int num = 1000; //设定卖票的数量
private static Ticket s = null; //通过单例设计模式保证对象的唯一性
private Ticket(){}
public static Ticket getTicket()
{
if (s==null)
{
synchronized(Ticket.class)
{
System.out.println(Thread.currentThread().getName()+"-----");
if(s==null)
s =new Ticket();
}
}
return s;
}
public void run()
{
while(num>0)
// try
// {
// Thread.sleep(1); //设定延时 为什么加上这句多线程就不运行呢?
// }
// catch (Exception e)
// {
// }
synchronized(Ticket.class)
{
System.out.println(Thread.currentThread().getName()+"sale..."+num);
--num;
}
}
}
class TicketDemo
{
public static void main(String[] args)
{
Ticket a = Ticket.getTicket();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
Thread t3 = new Thread(a);
t1.start();
t2.start();
t3.start();
}
}
复制代码
作者:
我手心里的宝
时间:
2013-3-20 09:23
先抢个沙发哈
作者:
孙晋学
时间:
2013-3-20 10:50
因为你少加了{}
在while循环的时候,加上sleep这部分代码后,while只包含sleep的代码块,来一个线程,睡了,来一个线程又睡了
public void run()
{
while(num>0){
try
{
Thread.sleep(1);
}
catch (Exception e)
{
}
synchronized(Ticket.class)
{
System.out.println(Thread.currentThread().getName()+"sale..."+num);
--num;
}
}
}
复制代码
作者:
张亚青
时间:
2013-3-20 11:04
本帖最后由 张亚青 于 2013-3-20 11:09 编辑
【问题】本问题中除了楼主的疑问之外还存在一个问题,总共有两个问题:
1、程序不运行。
2、就是最后会出现一个"Thread-1sale...-1"结果 ,但有可能这是楼主故意想要的结果。
【答案】
1、对于第一个问题,之所以程序不会运行,是因为,当加上try代码块的时候
必须把try代码块和 下面的Synchronized代码块包含到一起,成为while的循环体。
while (num>0)
{
try
{
Thread.sleep(1);
}
catch (Exception e)
{
}
synchronized(Ticket.class)
{
System.out.println(Thread.currentThread().getName()+"sale..."+num);
--num;
}
}
复制代码
不然的话 就会变成 :
while (num>0)//这时候while循环体只有try语句,会造成死锁而无法运行。
{
try
{
Thread.sleep(1);
}
catch (Exception e)
{
}
}
synchronized(Ticket.class)
{
System.out.println(Thread.currentThread().getName()+"sale..."+num);
--num;
}
复制代码
2、对于第二个问题,如果想要正确的代码应该改成:
while (num>0)
{
try
{
Thread.sleep(1);
}
catch (Exception e)
{
}
synchronized(Ticket.class)
{
if (num>0)//在此处再进行一次判断
{
System.out.println(Thread.currentThread().getName()+"sale..."+num);
--num;
}
}
}
复制代码
作者:
何仕映
时间:
2013-3-20 12:05
张亚青 发表于 2013-3-20 11:04
【问题】本问题中除了楼主的疑问之外还存在一个问题,总共有两个问题:
1、程序不运行。
2、就是最后会出现 ...
谢谢你的回答,明白了。谢谢。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2