出云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 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件