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 (标签-python|关键词-char)
  • ¥15 python+selenium,在新增时弹出了一个输入框
  • ¥15 苹果验机结果的api接口哪里有??单次调用1毛钱及以下。
  • ¥20 学生成绩管理系统设计
  • ¥15 来一个cc穿盾脚本开发者
  • ¥15 CST2023安装报错
  • ¥15 使用diffusionbert生成文字 结果是PAD和UNK怎么办
  • ¥15 有人懂怎么做大模型的客服系统吗?卡住了卡住了
  • ¥20 firefly-rk3399上启动卡住了
  • ¥15 如何删除这个虚拟音频