案例:卖票(简单实现版)及其出现的问题

public class SellTickets implements Runnable{
    //共有100张票
    private int tickets = 100;

    @Override
    public void run() {
        //票数大于0就买票,并告知是哪个窗口卖的
        //每卖一张后,总票数要减1
        //即使票没了也仍可能有人买票,所以使用死循环
        while (true) {
            if (tickets > 0) {
                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                tickets--;
            }
        }
    }
}

public class SellTicketsDemo {
    public static void main(String[] args) {
        SellTickets st = new SellTickets();

        Thread t1 = new Thread(st,"窗口1");
        Thread t2 = new Thread(st,"窗口2");
        Thread t3 = new Thread(st,"窗口3");

        t1.start();
        t2.start();
        t3.start();
    }
}

运行结果:

仅仅是练习实现而已,还有很多后续问题没有解决。


 

出现的问题:

1.出现了多个窗口同时出售同一张票的情况

2.当加入线程控制方法,来控制出票时间时,会出现结果为负数的情况

加入sleep方法来控制出票时间

while (true) {
            if (tickets > 0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                tickets--;
            }

运行结果:


 先分析出现问题1的原因:

假设线程都按照正常的顺序执行,由于线程的随机性,在1号窗口处于出票时间时(此时出售第100张票),2号窗口线程被执行了,那么2号窗口此时也需要经历一个出票的时间,3号窗口同理。

那么按照顺序执行,当1号窗口在出售第100张票时而未作减少票数操作前,2号窗口此时刚好也运行到售票阶段,那么此时两个窗口都会出售第100张票。3好窗口同理,所以会造成三个窗口同时出售一张票的情况。

 

分析出现问题2的原因:

假设此时只剩下第1张票还未出售,1号窗口成功被执行并且总票数减一,此时总票数变为0张,1号窗口不会被执行,但是此时2号窗口刚好度过出票时间的100毫秒,那么2号此时将会在控制台输出:正在出售第0张票,接下来执行总票数减1的操作,那么当3号窗口刚好也度过出票时间100秒,被执行时,就会在控制台输出:正在出现第-1张票。

posted @ 2020-04-29 15:14  硬盘红了  阅读(303)  评论(0编辑  收藏  举报