java多线程售票系统

多线程售票系统:所有线程都会抢第一张票问题

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


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值