黑马程序员技术交流社区
标题:
多线程问题5
[打印本页]
作者:
ぺsimon☆
时间:
2013-5-16 00:04
标题:
多线程问题5
本帖最后由 ぺsimon☆ 于 2013-5-16 08:47 编辑
/*
继承Thread类做一个卖票程序
为什么程序的运行结果有0号票呢,哥们?
*/
class Ticket extends Thread
{
private static int ticket=100;
Object obj=new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(ticket>0)
{
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"..."+ticket--);
}
}
}
}
}
class TicketOne
{
public static void main(String[] args)
{
Ticket t1=new Ticket();
t1.start();
Ticket t2=new Ticket();
t2.start();
}
}
复制代码
作者:
刘学明
时间:
2013-5-16 00:13
{:soso_e140:}真不知道还是假不知道啊
作者:
ぺsimon☆
时间:
2013-5-16 00:16
刘学明 发表于 2013-5-16 00:13
真不知道还是假不知道啊
是真不知道啊,哥们
作者:
librazeng
时间:
2013-5-16 00:37
为什么出现0?
因为t1和t2持有不同的锁。t1和t2分别new了自己Object对象,因此synchronized(obj)持有的锁是不同的,假设当Thread-o执行到ticket=1时,if(ticket>0),满足,然后sleep(10)睡一会儿,此时Thread-1抢到执行权,通过ticket--打印1,并将ticket改为0,这时Thread睡醒了,拿着值为0的ticket输出了!
解决办法:1. 将两条线程的锁同步,可将Object变量改为静态的,即static Object obj=new Object();
2.把if(ticket>0),改为while(ticket>0),每个线程睡醒后都要判断ticket的值。
作者:
尖卡斌引
时间:
2013-5-16 02:15
此程序的第33和36行分别创建了两个Ticket对象 t1和t2.
每个Ticket对象中都有一个私有的 ticket =100. 这就相当于有了200张票。
而且每个对象都有一个 obj 对象 这就使得线程使用的锁不是同一个锁。
所以就出现了
多线程错误.jpg
(48.51 KB, 下载次数: 2)
下载附件
2013-5-16 02:01 上传
同样的票被卖了两次和出现0号票的情况
修改后的主函数代码
public static void main(String[] args)
{
Ticket t = new Ticket(); //创建一个Ticket对象,保证了资源(票)的唯一,和锁的唯一;
Thread t1 = new Thread(t); //创建两个线程,操作同一个资源(票)使用的也是同一个锁obj;
Thread t2 = new Thread(t);
t1.start();
t2.start();
}
作者:
ぺsimon☆
时间:
2013-5-16 08:47
看来我对多线程掌握得真的不是那么好啊,谢谢大家的解答,我明白了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2