java 多线程模拟火车售票系统问题

packagesocket;publicclassTest{publicstaticvoidmain(String[]args){TestThreadtt=newTest... package socket;

public class Test
{
public static void main(String [] args)
{
TestThread tt=new TestThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}

}
class TestThread implements Runnable
{
int ticket=10;
String str=" ";
public void run()
{
while(ticket>0)
{
synchronized(str)
{
System.out.println(Thread.currentThread().getName()+":ticket "+ticket+" is saling");
ticket--;
}
}
}
}
输出结果如下:
Thread-0:ticket 10 is saling
Thread-1:ticket 9 is saling
Thread-1:ticket 8 is saling
Thread-0:ticket 7 is saling
Thread-0:ticket 6 is saling
Thread-0:ticket 5 is saling
Thread-0:ticket 4 is saling
Thread-0:ticket 3 is saling
Thread-2:ticket 2 is saling
Thread-2:ticket 1 is saling
Thread-3:ticket 0 is saling
Thread-1:ticket -1 is saling
Thread-0:ticket -2 is saling
不知是什么原因,这是书上的源码,好像没有问题。
展开
 我来答
铂金羊羊羊
推荐于2016-03-27 · TA获得超过1043个赞
知道小有建树答主
回答量:230
采纳率:100%
帮助的人:212万
展开全部
在synchronized(str) 里加一句 if(ticket > 0) //判断是否有余票,没有余票还卖什么?
也就是这样:
package socket;

public class Test
{
public static void main(String [] args)
{
TestThread tt=new TestThread();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
}

}
class TestThread implements Runnable
{
int ticket=10;
String str=" ";
public void run()
{
while(ticket>0)
{
synchronized(str)
{
if(ticket > 0 ) {
System.out.println(Thread.currentThread().getName()+":ticket "+ticket+" is saling");
ticket--;
}
}
}
}
}

你的while循环只是超出票数的循环,在同步里面还要有判断是否有票的条件.因为里面同步的时候除了一个线程在执行外,其它几个都在等待,而此时并没有跳出循环,当然会出现负数了.
当然把while判断放到同步代码里面去也可以.不过这样就没有超出票数的判断了,实际应用中应该有个超出票数的判断.. 例如 :for(int i=0;i<100;i++) //同步检测 只有5张票,显示100张,实际上卖出的还是5张..用来检测同步是否正确...
追问
如果想统计出最后每一个窗口卖出了多少张票,怎么设计啊?
追答
写一个内部类操作就可以了....定义两个变量   x 和y    
Thread.currentThread().getName().equals("窗口一")时,x++ 否者 y++,这是两个窗口的,多个窗口的你就一个个判断就行了.很简单的...当然了,你要避免多次打印...你能搞定的....
hc19890819
2011-08-18 · 超过42用户采纳过TA的回答
知道答主
回答量:163
采纳率:0%
帮助的人:103万
展开全部
有问题,你看ticket>0程序才会运行,可是你这里ticket已经-2了,原因在于你这程序有多个线程造成的。根源是当程序运行到while(ticket>0)时(这时ticket = 1),这个另2个线程得到执行权也进来,并且执行到这里,他得到的ticket也是1,当线程夺回执行权后ticket执行3次,所以ticket变成-2了,
解决办法 把synchronized放到run方法前就可以啦
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
lishuyangok
2011-08-18
知道答主
回答量:9
采纳率:0%
帮助的人:1.5万
展开全部
你要把同步块放到循环的外面
程序开始的时候4个进程都满足(ticket>0)
但是只有一个能进去同步块,其他3个在等待。
等于0时还有线程在循环里面,同步块外面。
所以。。。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式