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]其实一段就可以了。

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

报告相同问题?

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题