出云coding 2021-09-24 07: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 07:24
    关注

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

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

报告相同问题?

问题事件

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

悬赏问题

  • ¥20 谁刷目标页面的uv记录器上数据,数据只记录跳转的数值
  • ¥30 数据库软件的安装方法
  • ¥15 一道以太网数据传输题
  • ¥15 python 下载群辉文件
  • ¥50 代码还没怎么运行但是需要代码功能调用数据
  • ¥15 vue请求不到数据,返回状态200,数据为html
  • ¥15 用白鹭引擎开发棋牌游戏的前端为什么这么难找
  • ¥35 哪位专业人士知道这是什么原件吗?哪里可以买到?
  • ¥15 关于#c##的问题:treenode反序列化后获取不到上一节点和下一节点,Fullpath和Handle报错
  • ¥15 一部手机能否同时用不同的app进入不同的直播间?
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部