1. 问题描述
实现一个模拟售票的场景,有 3 个站台,30张票,使用多线程实现
2. 创建一个 Station 类
要点:
- 构造函数设置线程名
- 使用静态类型存储余票数
- 使用
synchronized
锁,不同的窗口使用一个锁 - 使用延时模拟网络延迟(需要处理异常)
class Station extends java.lang.Thread{
// 构造函数,给线程名字
public Station (String name ) {
super(name);
}
static int ticketNumber = 30; // 使用静态类型,保持票数一致
static Object key = "abc"; // 钥匙
@Override
public void run() {
while (true) {
// 使用 synchronized 加锁的代码块同一时间内只有一个线程能访问,使用同一个锁
// 进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来
synchronized (key) {
if (ticketNumber > 0) {
ticketNumber--;
System.out.println(getName() + "卖出了第" + ticketNumber + "张票");
} else {
System.out.println("卖完啦!");
break;
}
}
// 延时 1s(需要处理异常)
try {
sleep(1000);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e);
}
}
}
};
3. 测试
创建 3 个窗口,三个线程同时启动:
public class TestThread {
public static void main(String[] args) {
Station station1 = new Station("窗口1");
Station station2 = new Station("窗口2");
Station station3 = new Station("窗口3");
// 启动线程
station1.start();
station2.start();
station3.start();
}
}
结果如下:
窗口1: 卖出了第1张票
窗口3: 卖出了第2张票
窗口2: 卖出了第3张票
窗口1: 卖出了第4张票
窗口2: 卖出了第5张票
窗口3: 卖出了第6张票
窗口1: 卖出了第7张票
窗口2: 卖出了第8张票
窗口3: 卖出了第9张票
窗口1: 卖出了第10张票
窗口2: 卖出了第11张票
窗口3: 卖出了第12张票
窗口1: 卖出了第13张票
窗口2: 卖出了第14张票
窗口3: 卖出了第15张票
窗口1: 卖出了第16张票
窗口3: 卖出了第17张票
窗口2: 卖出了第18张票
窗口1: 卖出了第19张票
窗口3: 卖出了第20张票
窗口2: 卖出了第21张票
窗口1: 卖出了第22张票
窗口2: 卖出了第23张票
窗口3: 卖出了第24张票
窗口1: 卖出了第25张票
窗口2: 卖出了第26张票
窗口3: 卖出了第27张票
窗口1: 卖出了第28张票
窗口2: 卖出了第29张票
窗口3: 卖出了第30张票
窗口1: 卖完啦!
窗口2: 卖完啦!
窗口3: 卖完啦!