Java多线程实现窗口售票的功能

在这个程序中我们一共售卖1-100号票,一共有4个窗口,首先我们看程序如下

package com.study.article1;

/**
 * @func 多线程实现窗口卖票.
 * @author 张俊强~
 * @time 2017/10/27 12:52
 * */
class Ticket implements Runnable {
    private int ticket = 1000;

    public void salesTickets() {
        synchronized (this) {   //加同步锁
            if (ticket > 0) {   //再次判断是否还有余票
                System.out.println(Thread.currentThread().getName() + "正在卖第[ " + ticket-- + " ]张票...");
            }
        }
    }

    public void run() {
        while (ticket > 0) {    //当还有余票的时候继续卖票
            salesTickets();     //调用卖票方法

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class TicketDemo {
    public static void main(String[] args) {
        Ticket t = new Ticket();

        Thread w1 = new Thread(t,"窗口一");// 创建四个窗口
        Thread w2 = new Thread(t,"窗口二");
        Thread w3 = new Thread(t,"窗口三");
        Thread w4 = new Thread(t,"窗口四");
        w1.start();
        w2.start();
        w3.start();
        w4.start();
    }
}

针对以上的程序做一下两点说明

(1).为什么要加同步锁synchronized (this)?

如果不加同步锁的话会出现这样子的情况(只举一个例子)

    public void salesTickets() {
        //synchronized (this) { //加同步锁
            //if (ticket > 0) {
                // 这里标志位        【位置一】
                System.out.println(Thread.currentThread().getName() + "正在卖第[ " + ticket-- + " ]张票...");//【卖票操作】
                // 这里标志位        【位置二】
            //}
        //}
    }

当票库中只有一张票的时候,一号线程走到了【位置一】
再他刚准备执行【卖票操作】的时候,二号线程走到了【位置一】(没有加锁就可以进来)
这时候一号线程卖完了票ticket=0,二号线程就把第零张票给卖出去了

(2).为什么要两次判断是否还有余票?

有的同学就会有疑问,我加一个同步锁就是啦,为什么还要两次判断是否还有余票呢?

    public void run() {
        while (ticket > 0) {    //当还有余票的时候继续卖票
            // 这里标志为        【位置一】
            salesTickets();     //调用卖票方法

            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

当票库中只有一张票的时候,一号线程走到了【位置一】
再他刚准备执行【调用卖票方法】的时候,二号,三号线程都走到了【位置一】
在后面同步方法里面又没有做是否还有余票的判断,就会把o号-1号也给卖了。

设想,这样子如果是在12306,岂不是很混乱,一群人拿着0号,-1号,-2号……车票一脸懵逼的上了车……


你可能感兴趣的:([,面试常见问题,],java,多线程,窗口售票)