nor1take 2022-05-24 19:02 采纳率: 57.1%
浏览 79
已结题

java中,某线程调用join()方法后,再调用wait(),为什么其他线程没有执行?

java中,某线程调用join()方法后,再调用wait(),为什么其他线程没有执行?

如何在某线程调用join()方法后,让wait()起效果?

题目:模拟3个人排队买票:张某、李某和赵某要买电影票,售票员只有3张5元钱的,电影票5元一张。张某拿一张20元排在李某的前面买票,李某排在赵某的前面拿一张10元的买票,赵某拿一张5元买票。

class Changes {
    int num = 3;

    public synchronized void sell(int money) throws InterruptedException {
        System.out.println("顾客付了" + money + "元。");
        if (money == 5) {
            num++;
            System.out.println("零钱多了1张5元。");
            notify();
        }
        num -= ((money - 5) / 5);
        if (num < 0) {
            num = 0;
            System.out.println("零钱不足,先给下一名顾客售票。");
            wait(); //这里使用wait
        }
        System.out.println("售票成功!5元的零钱还有" + num + "张。");
    }
}

class Consumer extends Thread {
    public int money;
    Changes changes;

    public Consumer(int money, Changes changes) {
        this.money = money;
        this.changes = changes;
    }

    public void run() {
        try {
            changes.sell(money);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        Changes changes = new Changes();
        Consumer consumer1 = new Consumer(20, changes);
        Consumer consumer2 = new Consumer(10, changes);
        Consumer consumer3 = new Consumer(5, changes);
        consumer1.start();
        consumer1.join();
        consumer2.start();
        consumer2.join();
        consumer3.start();
    }
}

预期效果是依次运行consumer1、consumer2、consumer3。
结果consumer2调用wait后并没有运行consumer3,我猜原因是consumer2调用了join,consumer3必须等consumer2结束才执行?
如何才能达到预期效果?

img

  • 写回答

1条回答 默认 最新

  • 皮蛋不吃粥 2022-05-24 19:29
    关注

    调整了下,这个地方是不需要join的,需要一起去竞争,如果你都join有什么必要加锁呢,都不存在竞争;
    第二就是零钱不足不需要充值num=0;这里num是共享资源只要保证线程安全就行。你可以看看 有啥不懂问我

    class Changes {
        int num = 3;
    
        public synchronized void sell(int money) throws InterruptedException {
            String name = Thread.currentThread().getName();
            System.out.println("顾客:" + name + "付了" + money + "元。");
            if (money == 5) {
                num++;
                System.out.println("零钱多了1张5元。");
                notify();
            }
            num -= ((money - 5) / 5);
            if (num < 0) {
                System.out.println("零钱不足,先给下一名顾客售票。");
                wait(); //这里使用wait
            }
            System.out.println("售票给顾客:" + name + "成功!5元的零钱还有" + num + "张。");
        }
    }
    
    class Consumer extends Thread {
        public int money;
        Changes changes;
    
        public Consumer(int money, Changes changes) {
            this.money = money;
            this.changes = changes;
        }
    
        @Override
        public void run() {
            try {
                changes.sell(money);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) throws InterruptedException {
            Changes changes = new Changes();
            Consumer consumer1 = new Consumer(20, changes);
            Consumer consumer2 = new Consumer(10, changes);
            Consumer consumer3 = new Consumer(5, changes);
            consumer1.start();
    //        consumer1.join();
            consumer2.start();
    //        consumer2.join();
            consumer3.start();
        }
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 6月2日
  • 已采纳回答 5月25日
  • 修改了问题 5月24日
  • 创建了问题 5月24日

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度