用Java多线程来实现一个车站卖票的实例。
需求:3个窗口,一共20张票,推荐使用Runnable的方式来实现,
输出:输出当前卖票窗口的名称 + 正在卖第n张票,剩余n张票
安全问题:线程A在卖票的时候,其他线程不可卖同一张票。
例:线程A在卖第10张票,线程B也在卖第10张票,票的数量只会-1,而实际是-2,数据不一致,使用synchronized来保证线程安全、数据一致性
创建TicketsRunnable类
package com.ywt.mybatisplus.thread;
/**
* @author pc
* 实现多窗口卖票功能
*/
public class TicketsRunnable implements Runnable {
// 定义票数为20,静态变量保持数据的一致性
private static int ticketsCount = 20;
// 创建一个锁(也可以使用自己实例)
Object objectLock = new Object();
@Override
public void run() {
//如果票数大于0
while (ticketsCount > 0){
//调用方法
sellTicket();
try {
//休眠100ms,给其他窗口提供卖票的机会
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void sellTicket() {
// 加锁
synchronized (objectLock) {
//判断票数是否大于0
if (ticketsCount > 0) {
// 输出内容
// Thread.currentThread().getName()获取当前窗口名称
System.out.println(Thread.currentThread().getName() + "正在卖第" + ticketsCount + "张票," + "还剩" + (ticketsCount - 1) + "张票");
// 票数减1
ticketsCount--;
if (ticketsCount == 1) {
// 黑心窗口
System.out.println(Thread.currentThread().getName() + "正在卖最后一张票,加价10元");
ticketsCount--;
}
} else {
System.out.println("票已卖完");
}
}
}
}
创建TicketsRunnableMain类
package com.ywt.mybatisplus.thread;
public class TicketsRunnableMain {
public static void main(String[] args) {
TicketsRunnable ticketsRunnable = new TicketsRunnable();
Thread windows1 = new Thread(ticketsRunnable, "窗口1");
Thread windows2 = new Thread(ticketsRunnable, "窗口2");
Thread windows3 = new Thread(ticketsRunnable, "窗口3");
windows1.start();
windows2.start();
windows3.start();
}
}
然后运行Main方法