maomaoysq 2009-10-30 14:44
浏览 547
已采纳

java的多线程问题,结果出现负数情况

预想实现轮番取[color=red]单数[/color]票和[color=red]双号[/color]票的多线程出票过程

执行结果发现:
如果只执行两个进程,程序会卖出票号为“0”的票,如果再增加出票的线程就出现线程为[color=red]负[/color]数的情况了

[code="java"]
public class myFirst
{
public static void main(String[] args)
{
Q q = new Q();
new Thread(new SaleS(q)).start();
new Thread(new SaleD(q)).start();
new Thread(new SaleS(q)).start();
new Thread(new SaleD(q)).start();
}
}
class Q
{
private int tickets = 10;
public synchronized int get()
{
return tickets;
}
public synchronized void saleSingle()
{
if(tickets>0)
{
if(tickets % 2 ==0)
{
try {
wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
try
{
Thread.sleep(1000);
}
catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+
" is salling ticket "+ tickets--);
notify();
}
}
public synchronized void saleDouble()
{
if(tickets>0)
{
if(tickets % 2 ==1)
{
try {
wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
try
{
Thread.sleep(1000);
}
catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+
" is salling ticket "+ tickets--);
notify();
}
}
}
class SaleS implements Runnable
{
Q q = null;
public SaleS(Q q)
{this.q = q;}
public void run()
{
while(q.get()>=1)
{
q.saleSingle();
}
}
}
class SaleD implements Runnable
{
Q q = null;
public SaleD(Q q)
{this.q = q;}
public void run()
{
while(q.get()>=2)
{
q.saleDouble();
}
}
}
[/code]

  • 写回答

1条回答 默认 最新

  • JavaHero080 2009-11-02 15:33
    关注

    你的方法都[code="java"]synchronized[/code]了,也就意味着,当某一个线程在执行[code="java"]saleSingle()[/code]或者[code="java"]saleDouble()[/code]时,虽然检查了奇偶性,但在[code="java"]wait()[/code]时,其它线程是无法执行这些同步化方法时(single或double,都一起被上锁了)。
    所以结果是wait()结束然后出票,此时你并未做检查,所以不一定正确。
    逻辑上你必须不断wait只到条件成熟,比如把if改成while。不过那样很有可能死锁。你必须重新设计一下代码结构,最好不要[code="java"]synchronized[/code]整个方法,只要[code="java"]synchronized[/code]其实一段就可以了。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 vs2022无法联网
  • ¥15 TCP的客户端和服务器的互联
  • ¥15 VB.NET操作免驱摄像头
  • ¥15 笔记本上移动热点开关状态查询
  • ¥85 类鸟群Boids——仿真鸟群避障的相关问题
  • ¥15 CFEDEM自带算例错误,如何解决?
  • ¥15 有没有会使用flac3d软件的家人
  • ¥20 360摄像头无法解绑使用,请教解绑当前账号绑定问题,
  • ¥15 docker实践项目
  • ¥15 利用pthon计算薄膜结构的光导纳