• Java 多线程模拟售票系统(转)


    package ccb.ticket;
    
    import java.io.File;
    import java.util.ArrayList;
    /*
    功能实现:多线程模拟售票系统
    定义一个车票类,车票类拥有票号属性、  车票状态(未售、售出)属性和拥有者(String类型)属性;
        在主线程中定义一个票库(ArrayList数组列表)初始化票库并生产200张票;
    定义一个乘客类继承自线程类,有一个名字(String类型)属性, 乘客类每隔10毫秒就去票库中查看有没票,
        如果有票就抢一张过来 (把车票标为售出状态,并把车票的拥有者标为自己的名字), 每个乘客抢到20张票就停止运行。
    在主线程中创建10个乘客类并启动它们(开始抢票), 要求每个乘客抢到的票不连号,不能多抢或少抢。抢完后打印出每个人抢到的票号。
    */
    public class Main {
        //票库
        static ArrayList<Ticket> mTicketList = new ArrayList<Ticket>();
    
        public static void main(String[] args) {
            for (int i = 0; i < 200; i++) {
                Ticket t = new Ticket();
                t.ticketNum = i + 100;
                mTicketList.add(t);
            }
            Passenger[] passengers = new Passenger[5];
            for (int i = 0; i < 5; i++) {
                passengers[i] = new Passenger("passenger_" + i/*,mTicketList*/);
                passengers[i].start();
            }
    
            //等待所有乘客结束
            for (int i = 0; i < 5; i++) {
                try {
                    passengers[i].join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
    
            for (int i = 0; i < passengers.length; i++) {
                System.out.print(passengers[i].name + "抢到的票:");
                int tCnt = 0; //抢到的票数
                for (int j = 0; j < mTicketList.size(); j++) {
                    Ticket t = mTicketList.get(j);
    
                    if (t != null && t.owner != null && passengers[i] != null) {
                        if (t.owner.equals(passengers[i].name)) {
                            tCnt++;
                            System.out.print(t.ticketNum + ",");
                        }
                    }
                }
                System.out.println("总票数:" + tCnt);
            }
        }
    
    }
    

    购票人:

    package ccb.ticket;
    
    /**
     * 旅客线程(并发)
     */
    
    public class Passenger extends Thread {
        String name;//名字
        //ArrayList<Ticket> mTicketList ;
        int myTickets = 0;
    
        public Passenger(String name/*,ArrayList<Ticket> ticketList*/) {
            //mTicketList = ticketList;
            this.name = name;
        }
    
        @Override
        public void run() {
            //Main.mTicketList.get(0);
            while (myTickets < 20) {
                //开始抢票
                for (int i = 0; i < Main.mTicketList.size(); i++) {
                    Ticket t = Main.mTicketList.get(i); //取出第i张票
                    synchronized (t) { //synchronized (监视的竞争对象)
                        if (t.saledState == Ticket.STATE_NOT_SALED) {
                            //把车票标为售出状态
                            t.saledState = Ticket.STATE_SALED;
                            //把车票的拥有者标为自己的名字
                            t.owner = this.name;
                            myTickets++;
                            System.out.println(Thread.currentThread().getName() + this.name + " 抢到" + t.ticketNum + "号票");
                            break;
                        }
                    }
                    /*
                    boolean result = checkTicket(t);
                    if(result){
                        break;
                    }*/
                }
    
                try {
                    sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /*
         * synchronized 默认监视的竞争对象 : 为当前类对象,即this
         */
        public synchronized boolean checkTicket(Ticket t) {
            if (t.saledState == Ticket.STATE_NOT_SALED) {
                t.saledState = Ticket.STATE_SALED; //把车票标为售出状态
                t.owner = this.name; //把车票的拥有者标为自己的名字
                myTickets++;
                System.out.println(this.name + "抢到" + t.ticketNum + "号票");
                return true;
            }
            return false;
        }
    }
    

      车票:

    package ccb.ticket;
    
    public class Ticket {
        public static final boolean STATE_SALED = true;         //售出状态
        public static final boolean STATE_NOT_SALED = false;    //未售出状态
    
        public int ticketNum = 0;                           //票号
        public boolean saledState = STATE_NOT_SALED;        //初始状态: 未售
        public String owner = null;                         //拥有者
    }
    

      

      一个很好的示例,受到了很大的启发!原文出处记不起来了,侵删!

  • 相关阅读:
    P4049 [JSOI2007]合金
    CF1073C Vasya and Robot
    输出100以内奇数,偶数,质数,合数的脚本
    取/etc/password文件最后一个单词的最后一个字符
    window下进程退出后自动重启
    如何让DOS命令在新窗口打开
    dos命令关闭所有dos窗口
    使用jps查看JVM进程信息
    windows .bat批处理实现进程监控确保程序运行
    经典博客4(六尺帐篷)
  • 原文地址:https://www.cnblogs.com/jarod99/p/15488063.html
Copyright © 2020-2023  润新知