多线程售票系统:所有线程都会抢第一张票问题
要求用多线程设计一个模拟火车站售票大厅的工作情形。火车站有许多售票窗口,有些开放,有些不开放。用多个线程去订票,不能有两个或者以上的线程订到同一个票,当最后一张票卖掉时,再订就异常提示出票卖完了。每个窗口买票需要1-3秒的时间,每次卖票需要打印出买票的时间和买票的窗口名。
写出来以后,发现一个有意思的现象,所有线程都会抢第一张票,但是后面的线程正常,加了 synchronized锁,于是开始着手研究。
开始在想可不可以在run方法里写上this.wait();然后再主线程中写一个run方法,this.notifyAll();,然后发现不可以,我推断可能是因为代码有问题,主类中的run方法启动后又停止了,陷入了死循环;也可能是因为内部类中,对象指向不是主类中的对象。
于是改变思路,在start的时候使用for循环,保证同时启动,得到了正确的结果
//代码相当简陋,希望有大神可以帮忙解决下为什么用notifyAll方法启动失败(死循环)
附上修改后的源码
package process;
import java.util.Scanner;
import java.util.Vector;
public class process implements Runnable{
private static int num;
static int ticket;
@Override
public void run() {
while (ticket < num) {
long time1 = System.currentTimeMillis();
synchronized(process.this){
if (ticket < num) {
try {
this.notifyAll();
Thread.sleep(55);
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else break;
long time2 = System.currentTimeMillis();
long time = time2 - time1;
if (ticket < num) {
System.out.println("票数:" + (ticket + 1) + " ");
System.out.println("窗口" + Thread.currentThread().getName() + " " + "耗时:" + time);
ticket = ticket + 1;
}
}
}
}
public static void main(String[] args) {
int counter, n1 = 0, i = 0, number;
Vector<Integer> v = new Vector<Integer>();
System.out.print("请输入总票数:");
Scanner sc = new Scanner(System.in);
num = sc.nextInt();
System.out.print("请输入窗口的总个数:");
counter = sc.nextInt();
System.out.println("请输入工作的窗口(以0结束):");
number = sc.nextInt();
while (number < counter && number != 0) {
// 不在集合中,就添加
v.add(number);
number = sc.nextInt();
}
process myThread1 = new process();
for (i = 0; i < v.size(); i++) {
new Thread(myThread1, "售票点" + v.elementAt(i)).start();
}
}
}
本文讨论了一个多线程环境下模拟火车站售票系统的实现,遇到的问题及解决方案。在设计中,所有线程都会争抢第一张票,通过使用`synchronized`关键字解决了线程安全问题。作者尝试使用`wait()`和`notifyAll()`来控制线程,但遇到了死循环,最终通过在启动线程时使用循环实现了正确的并发行为。代码示例展示了如何避免线程间的不正确交互,确保售票的有序进行。
539

被折叠的 条评论
为什么被折叠?



