一餐厅有50个座位可供用餐者就餐,超过50人时只能排队等候,待空出座位方可就餐

一餐厅有50个座位可供用餐者就餐,超过50人时只能排队等候,待空出座位方可就餐,如何用管程实现?



public class Restaurant {


    /**
     * 最大座位数
     */
    static private int MAX_SEAT = 50;

    /**
     * 当前已经来的客人
     */
    static private AtomicInteger SEAT_CUSTOMER = new AtomicInteger(0);

    /**
     * 排队队列
     */
    LinkedBlockingQueue SEAT_QUEUE = new LinkedBlockingQueue();

    public static void main(String[] args) {
        Restaurant restaurant = new Restaurant();

        //放入1000个顾客测试 1秒放入一个
        Thread customer = new Thread(() -> {
            for (int i = 0; i < 500; i++) {
                restaurant.customerComIn(System.currentTimeMillis());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        customer.start();

        Thread customer2 = new Thread(() -> {
            for (int i = 0; i < 500; i++) {
                restaurant.customerComIn(System.currentTimeMillis());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        customer2.start();


        //此线程定时移除乘客,代表结账 没2秒执行一次
        new Thread(() -> {
            while (true) {
                restaurant.customerComInLeave();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }).start();

    }

    /**
     * 顾客离开
     */
    private void customerComInLeave() {
        synchronized (SEAT_CUSTOMER) {
            if (SEAT_CUSTOMER.get() <= 0) {
                return;
            }
            SEAT_CUSTOMER.decrementAndGet();
            System.out.println(Thread.currentThread().getName() + "当前离开顾客1位");
            //安排队列中的乘客落座
            customerSeat();
        }
    }

    /**
     * 从队列中安排顾客落座
     */
    private void customerSeat() {
        while (true) {
            //如果没有等待的顾客则返回
            if (SEAT_QUEUE.size() == 0) {
                System.out.println("没有顾客等待");
                return;
            }
            Object num = SEAT_QUEUE.peek();
            if (num != null) {
                boolean seatResult = seat(Long.valueOf(num.toString()));
                if (seatResult) {
                    SEAT_CUSTOMER.getAndIncrement();
                    System.out.println("有顾客结账,队列中的: " + num + "落座;队列中还有人: " + SEAT_QUEUE.toString());
                    SEAT_QUEUE.remove(num);
                } else {
                    SEAT_QUEUE.add(num);
                    return;
                }
            }

        }

    }


    /**
     * 顾客来了
     * 这地方暂时用一个int 可以改造成一个对象
     * 目前只考虑单客人
     *
     * @return true:代表落座成功,false:代表等待
     */
    private boolean customerComIn(Long num) {
        synchronized (SEAT_CUSTOMER) {
            boolean seatResult = seat(num);
            if (seatResult) {
                SEAT_CUSTOMER.getAndIncrement();
            } else {
                SEAT_QUEUE.add(num);
            }
            return seatResult;
        }
    }

    private boolean seat(Long num) {
        //超过50人的时候
        if (SEAT_CUSTOMER.get() > MAX_SEAT) {
            System.out.println(Thread.currentThread().getName() + "当前人数: " + SEAT_CUSTOMER.get() + ";请等待: " + SEAT_QUEUE.size());
            return false;
        } else {
            System.out.println(Thread.currentThread().getName() + "当前人数: " + SEAT_CUSTOMER.get() + ";请入座");
            return true;
        }
    }
}

运行结果: 
Thread-2当前人数: 51;请等待: 17
Thread-0当前人数: 51;请等待: 18
Thread-1当前人数: 51;请等待: 19
Thread-0当前人数: 51;请等待: 20
Thread-1当前人数: 51;请等待: 21
Thread-2当前离开顾客1位
Thread-2当前人数: 50;请入座
有顾客结账,队列中的: 1649695145832落座;队列中还有人:

给餐厅的点餐人数初始化一个0值,每当有人点餐该值加1,有人结账时该值减1,点餐前先获取该值,小于50允许点餐,大于等于50提示餐位已满,请等待

cobegin
process eat_i //i=1,2,3,....,
{
Restaurant.eating();
}
coend

Semaphore semaphore = new Semaphore(50); 加队列

这个需要软硬件结合
第一种,半自动(人工辅助)
50个位置是要输入电脑的,
换位也是要输入电脑的,换位需要注意,没上的菜也要换桌(跟着号码牌即可)
客未满,服务员需要让顾客点单,问清几个人,给个号码牌,如果服务员有PDA,当时就输入,某号码牌坐哪一桌,有几个人。
吃完后,顾客买单,服务员输入,某某号牌买单,根据点单占位数自动得出某桌空出多少个位


自动化
这个没意义,无法真正实施,可能会造成混乱,比如逃单,你都不知道桌子到底空没空。