多线程售票系统:所有线程都会抢第一张票问题
要求用多线程设计一个模拟火车站售票大厅的工作情形。火车站有许多售票窗口,有些开放,有些不开放。用多个线程去订票,不能有两个或者以上的线程订到同一个票,当最后一张票卖掉时,再订就异常提示出票卖完了。每个窗口买票需要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(); } } }