注册 登录
编程论坛 JAVA论坛

多线程模拟卖票案例

shelei 发布于 2016-06-22 11:43, 3256 次点击
某电影院正在上映某大片,共100张票,而他又3个售票窗口售票,请设计一个程序模拟该电影院售票。

class SellTicket implements runnable {
        private int tickets = 100;
        public void run() {
 while (true) {
       if(tickets>0){
                 system.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
                }
            }
       }  
}

public class SellTicketDemo {

        SellTicket st = new SellTicket();

        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正在出售第99张票
窗口1正在出售第98张票
窗口1正在出售第97张票
窗口1正在出售第96张票
窗口1正在出售第95张票
窗口1正在出售第94张票
窗口1正在出售第93张票
窗口1正在出售第92张票
窗口1正在出售第91张票
窗口2正在出售第100张票
窗口1正在出售第89张票
     .
     .
     .
     .

我的问题是为什么会是第99张票先卖出去而不是第一百张票?代码里tickets明明是从100开始执行的啊,那不是应该先卖第100张票?请各路大神帮帮忙解答下 不胜感激
2 回复
#2
jinjoxie2016-06-23 10:15
你的代码循环中几乎没有停顿,测试中大都部的输出都会被其中一个线程占用的。你代码中可以看成有4个线程,3个“卖票窗口”1个“输出窗口”,你测试的结果就是线程2“卖票窗口2”先卖出了100的票,但是“输出窗口”却一直被线程1“卖票窗口1”占用(几乎没停顿),到线程1“卖票窗口1”卖到91时应该卡了一下(90号票都没抢到吧,只抢到89),被窗口2抢到了“输出窗口”,它终于“说”出“出售第100张票”,之后“输出窗口”又被“卖票窗口1”抢回。
处理方法为: 在输出和“卖票”tickets--代码块中加个线程同步
        public void run() {
                while (tickets>0){
                    //线程同步
                    synchronized (this) {
                         if(tickets>0) System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票");
                    }
//可以加上随机休眠时间,停顿一下避免同一个窗口占了所有资源
                    try {
                        Thread.sleep((long) (Math.random()*1000));
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
//
                }
       }  
#3
TsugumiYuu2016-06-23 14:14
建议看一下线程安全问题及解决方法,及给每个窗口调用前先暂停check一下,如果你卖到最后一张票,如果三个窗口同时售票,就会出现问题
1