出云coding 2021-09-24 15:13 采纳率: 100%
浏览 54
已结题

求帮忙,不定义为static会陷入死锁,为什么?

static tickets seller=new tickets();这个样定义
输出结果:
赵先生稍等
周先生完成售票
李先生完成售票
找给孙先生一张5元,完成售票
找给钱先生一张10元和一张5元,完成售票
找给赵先生一张10元,完成售票
Process finished with exit code 0

tickets seller=new tickets();找个样定义
输出结果:
钱先生稍等一下
赵先生稍等
找给孙先生一张5元,完成售票
周先生完成售票
李先生完成售票

为什么会陷入死锁?

package Test04.test3;


/*
题目:
编写Java应用程序模拟5个人排队买票。售票员只有1张五元的钱,电影票五元钱一张。假设5个人的名字及排队顺序是:
赵、钱、孙、李、周。“赵”拿1张二十元的人民币买2张票,“钱”拿1张二十元的人民币买1张票,“孙”1张十元的人民币买1张票,
“李”拿1张十元的人民币买2张票,“周”拿1张五元的人民币买1张票。
要求售票员按如下规则找赎:
(1)二十元买2张票,找零:1张十元;不许找零2张五元。
(2)二十元买1张票,找零:1张十元,1张五元;不许找零3张五元。
(3)十元买一张票,找零1张五元。
 */
class tickets{
    //售票手机钱的个数
    static int fiveNumber=1,tenNumber=0,twentyNumber=0;
    //买票人的钱和需要票数;
    public synchronized void check(int money,int count)  {
        String name=Thread.currentThread().getName();
        //买2张票,付20元,应找回一张10元
        if(money==20&&count==2){
            twentyNumber++;//先将钱收下
            if(tenNumber<1){
                try {
                    System.out.println(name+"稍等");
                    this.wait();
                } catch (InterruptedException e) {
                    System.out.println("有内鬼,终止交易");
                }
            }//钱不够就让他等一会
            while(tenNumber<1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {System.out.println("有内鬼,终止交易");}
            }//,之后的没有办法成功找钱,就继续进入等待状态
            tenNumber--;//找钱
            System.out.println("找给"+name+"一张10元,完成售票");
            notify();
        }
        else if(money==20&&count==1){
            //买一张票,付20元
            twentyNumber++;
            if(tenNumber<1||fiveNumber<1){
                try {
                    System.out.println(name+"稍等一下");
                    this.wait();
                } catch (InterruptedException e) {System.out.println("有内鬼,终止交易");}
            }
            while(tenNumber<1||fiveNumber<1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {System.out.println("有内鬼,终止交易");}
            }//,之后的没有办法成功找钱,就继续进入等待状态
            tenNumber--;
            fiveNumber--;
            System.out.println("找给"+name+"一张10元和一张5元,完成售票");
            notify();
        }
        else if(money==10&&count==1){
            tenNumber++;
            if(fiveNumber<1){
                try {
                    System.out.println(name+"稍等一下");
                    this.wait();
                } catch (InterruptedException e) {System.out.println("有内鬼,终止交易");}
            }
            while(fiveNumber<1) {
                try {
                    this.wait();
                } catch (InterruptedException e) {System.out.println("有内鬼,终止交易");}
            }//没有办法成功找钱,就继续进入等待状态
            fiveNumber--;
            System.out.println("找给"+name+"一张5元,完成售票");
            notify();
        }
        else if(money==10&&count==2){
            tenNumber++;
            System.out.println(name+"完成售票");
            notify();
        }
        else if(money==5&&count==1){
            fiveNumber++;
            System.out.println(name+"完成售票");
            notify();
        }

    }
}
public class buyTicket implements Runnable{

   static tickets seller=new tickets();
    public void run() {

        synchronized (this.seller){
            if (Thread.currentThread().getName().equals("赵先生")){
                seller.check(20,2);
            }
            else if(Thread.currentThread().getName().equals("钱先生")){
                seller.check(20,1);
            }
            else if(Thread.currentThread().getName().equals("孙先生")){
                seller.check(10,1);
            }
            else if(Thread.currentThread().getName().equals("李先生")){
                seller.check(10,2);
            }
            else if(Thread.currentThread().getName().equals("周先生")){
                seller.check(5,1);
            }
        }
    }

    public static void main(String[] args) {

        new Thread(new buyTicket(),"赵先生").start();
        new Thread(new buyTicket(),"钱先生").start();
        new Thread(new buyTicket(),"孙先生").start();
        new Thread(new buyTicket(),"李先生").start();
        new Thread(new buyTicket(),"周先生").start();

    }
}
/*
static tickets seller=new tickets();
赵先生稍等
周先生完成售票
李先生完成售票
找给孙先生一张5元,完成售票
找给钱先生一张10元和一张5元,完成售票
找给赵先生一张10元,完成售票

Process finished with exit code 0
 */
/*
tickets seller=new tickets();
钱先生稍等一下
赵先生稍等
找给孙先生一张5元,完成售票
周先生完成售票
李先生完成售票

 */

  • 写回答

2条回答 默认 最新

  • Winson.J 2021-09-24 15:24
    关注

    加static 所有buyTicket 对象都共享tickets 对象,94行锁住的是同一个对象,锁才有用;
    不加static, 每个buyTicket 都有做自己的tickets对象, 94行锁的是不同的对象,等于没有锁;

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 10月2日
  • 已采纳回答 9月24日
  • 创建了问题 9月24日

悬赏问题

  • ¥15 r语言蛋白组学相关问题
  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器