wait、notify、notifyAll实战案例之模拟餐厅排队系统

​ 首先,为什么要做这个案例?一方面是我想给大家介绍一下在多线程中wait、notify、notifyAll的简单用法和一些注意事项,另一个方面是我自己也想研究这种餐厅排队系统的实现原理。这个案例仅代表我个人的一些比较的简单想法,具体的更复杂业务并未涉及。但最基本的几个业务还是要有的。这个案例实现的几个简单的基本业务如下:

一、餐厅座位管理

​ 餐厅的座位是可以变化的,在这里我给了一个变量seatNumber可以动态修改餐厅座位数量。当然,在客户就餐后我们需要记录的是客户就餐当时的已使用座位数useNumber,以便于后期通过剩余座位号来实现叫号逻辑。

二、用户手动取号

​ 用户手动取号,用户具体是如何取号。这里我并不关心,取号的方式有多种方式,微信公众号取号,小程序取号等等。主要是后台实现用户取号的过程。

​ 我在这里是通过一个线程代表一个客户,以线程的方式绑定共享的排队号码容器,这个可以使用ThreadLocal类来实现。当然也可以使用Map容器storage来绑定。在这里,我使用的是后者。假设有这么一个容器,我们的客户和他取到的号码就能绑定在一起。那么取号过程中,也需要一个可以一直递增的号码takeNumber,后续取号将一直使用。

三、系统自动叫号

​ 系统自动叫号,需要两个变量,最新叫号curCallNumber,也可以说是当前叫号。上次叫号prevCallNumber。叫号过程中会结合座位剩余和这两个变量。

四、餐厅收桌维护

​ 餐厅运营过程中,座位是会重复清理干净给新客户使用,这个过程也要加入到整个系统实现,以维持整个排队容器正常使用。

​ 当然还有用户延号问题等等,这里我就不一一给大家分析。接下来我们主要来实现上面的几个基本业务。

代码实现如下:

主要几个业务方法都在Counter类下,为了线程安全,我在每个业务方法上加synchronized关键字。

而且wait、notify、notifyAll都需要在加锁的前提下使用

/**
 * @author 小吉
 * @description 简单自动排队实现
 * @date 2020/7/5
 */
public class Counter {
   

    private int takeNumber;//取号
    private int curCallNumber;//最新叫号
    private int prevCallNumber;//上次叫号
    private int useNumber;//餐厅已使用座位数
    private int seatNumber;//餐厅总座位数
    private Map<String,Integer> storage;//排队号码

    public Counter(int seatNumber){
   
        this.seatNumber = seatNumber;
        this.storage = new HashMap<>();
    }

    /**
     * 取号
     */
    public synchronized void takeNumber(){
   
        String name = Thread.currentThread().getName();
        try {
   
            //模拟用户取号
            storage.put(name,++takeNumber);
            System.out.println("您好," + name + "!取号成功,您的号码是" + takeNumber + ",当前叫号是" + curCallNumber + ",前面还有" + (takeNumber - curCallNumber - 1) + "桌");
            //当前用户手持号码大于最新叫号则需要等待
            while (storage.get(name) > curCallNumber){
   
                //模拟用户等待时间过长时获取进度(wait超时机制)
                wait((new Random().nextInt(60) + 1) * 1000);
                if(storage.get(name) > curCallNumber){
   
                    getCurrentProgress
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值