Java 多线程票务系统:模拟窗口售票与线程安全问题
以下是一个没有使用同步技术的 Java 多线程程序,模拟三个窗口同时卖 100 张票的情况:
public class TicketSeller implements Runnable {
private int tickets = 100;
public void run() {
while (tickets > 0) {
System.out.println(Thread.currentThread().getName() + ' sells ticket ' + tickets--);
}
}
public static void main(String[] args) {
TicketSeller ticketSeller = new TicketSeller();
new Thread(ticketSeller, 'Window 1').start();
new Thread(ticketSeller, 'Window 2').start();
new Thread(ticketSeller, 'Window 3').start();
}
}
在运行程序时,可能会看到以下输出:
Window 1 sells ticket 100
Window 1 sells ticket 99
Window 3 sells ticket 100
Window 2 sells ticket 100
Window 1 sells ticket 98
Window 3 sells ticket 99
Window 1 sells ticket 97
Window 2 sells ticket 98
Window 1 sells ticket 96
Window 3 sells ticket 98
Window 2 sells ticket 97
Window 1 sells ticket 95
Window 3 sells ticket 97
Window 2 sells ticket 96
Window 1 sells ticket 94
Window 3 sells ticket 96
Window 2 sells ticket 95
Window 1 sells ticket 93
Window 3 sells ticket 95
Window 2 sells ticket 94
...
从输出中可以看出,三个窗口在卖票时出现了错误,有些票被重复卖掉了。这是因为线程之间没有进行同步,多个线程同时对 tickets 变量进行修改,导致出现了线程安全问题。
要解决这个问题,可以使用同步技术,比如使用 synchronized 关键字来保证多个线程对 tickets 变量的访问是互斥的:
public class TicketSeller implements Runnable {
private int tickets = 100;
public void run() {
while (true) {
synchronized (this) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + ' sells ticket ' + tickets--);
} else {
break;
}
}
}
}
public static void main(String[] args) {
TicketSeller ticketSeller = new TicketSeller();
new Thread(ticketSeller, 'Window 1').start();
new Thread(ticketSeller, 'Window 2').start();
new Thread(ticketSeller, 'Window 3').start();
}
}
在运行程序时,可以看到所有的票都被正确地卖掉了。
原文地址: https://www.cveoy.top/t/topic/off0 著作权归作者所有。请勿转载和采集!