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
不知是什么原因,这是书上的源码,好像没有问题。 展开
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
不知是什么原因,这是书上的源码,好像没有问题。 展开
3个回答
展开全部
在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张..用来检测同步是否正确...
也就是这样:
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++,这是两个窗口的,多个窗口的你就一个个判断就行了.很简单的...当然了,你要避免多次打印...你能搞定的....
展开全部
有问题,你看ticket>0程序才会运行,可是你这里ticket已经-2了,原因在于你这程序有多个线程造成的。根源是当程序运行到while(ticket>0)时(这时ticket = 1),这个另2个线程得到执行权也进来,并且执行到这里,他得到的ticket也是1,当线程夺回执行权后ticket执行3次,所以ticket变成-2了,
解决办法 把synchronized放到run方法前就可以啦
解决办法 把synchronized放到run方法前就可以啦
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你要把同步块放到循环的外面
程序开始的时候4个进程都满足(ticket>0)
但是只有一个能进去同步块,其他3个在等待。
等于0时还有线程在循环里面,同步块外面。
所以。。。
程序开始的时候4个进程都满足(ticket>0)
但是只有一个能进去同步块,其他3个在等待。
等于0时还有线程在循环里面,同步块外面。
所以。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询