# 题目

设计并实现某火车票售票系统的放票功能:

某车次预留 100 张有座, 在每晚 8 点开启放票功能,每隔 30 分钟随机放出 10 张票。

简单模拟放票、购票功能:显示客户在某时刻抢到某号码的票。
模拟服务器放票,客户端购票功能:服务器显示某时刻放出某些票,在某时刻卖出某张票的信息;客户端显示某时刻买走某张票的信息。

# 思路与代码

服务器为 Producer 类,客户端为 Customer 类,均继承 Thread 实现多线程,然后一个 Tickets 类,表示余票,一个 MyTime 类表示时间(

源代码下载在这儿:cos_javatest2

MyTime 类:passM 函数表示过去 minute 分钟

public class MyTime {
    int hour;
    int minute;
    public MyTime(int hour, int minute) {
        this.hour = hour%24;
        this.minute = minute%60;
    }
    public synchronized void printTime() {
        System.out.printf("%02d:%02d ", hour, minute);
    }
    public synchronized void passM(int minute) {
        this.minute += minute;
        if(this.minute >= 60) {
            ++this.hour;
            this.minute %= 60;
        }
        this.hour %= 24;
    }
    @Override
    public String toString() {
        return "MyTime{" +
                "hour=" + hour +
                ", minte=" + minute +
                '}';
    }
}

Tickets 类:

重点,total 为总共预留的票数(100),time 为时间,cid 表示售票编号,已售出 1 票则为 1,pid 为存票编号,存了 10 张则为 10,available 表示是否还有余票,作为同步的标志。初始化均为 0,Tickets 为两个线程所共享的对象

import java.util.List;
import java.util.Stack;
public class Tickets {
    int total;          // 票总数
    MyTime time;        // 当前时间
    int cid;            // 售票序号
    int pid;            // 存票序号
    boolean available;      // 是否有余票
    public Tickets(int total, MyTime time) {
        this.total = total;
        this.time = time;
        pid = cid = 0;
        available = false;
    }
    public synchronized void passM(int minute) {
        time.passM(minute);
    }
    public synchronized void put(int num) {  // 同步方法,实现增加票的功能
        if(available) {
            System.out.println("暂未到存票时间,别急放(");
            try {wait();} catch (InterruptedException e) {e.printStackTrace();}
        }
        pid += num;
        time.printTime();
        System.out.printf("Producer 存票%d张, 当前余票:%d\n", num, pid-cid);
        available = true;
        notify();
    }
    public synchronized void sell() {  // 同步方法,实现卖出的功能
        if(!available) {
            System.out.printf("暂无余票,别急哦@Customer %d\n", cid);
            try {wait();} catch (InterruptedException e) {e.printStackTrace();}
        }
        time.printTime();
        if(available && cid < pid) {
            System.out.printf("Customer %d 购买了票 %d\n", ++cid, cid);
        }
        if(cid == pid) available = false;
        notify();
    }
}

Customer 类如下:继承 Thread,重载 run
假设每 3 分钟有一个顾客买票,与 Producer 类共享 Tickets 对象,所以 Tickets 内部的函数都需是同步的。

public class Custormer extends Thread{
    Tickets t = null;
    Custormer(Tickets t) {
        this.t = t;
    }
    @Override
    public void run() {
        System.out.println("Custormer start");
        while(t.cid < t.total) {
            t.sell();
            t.passM(3);
            try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace();}
        }
        System.out.println("Custormer ends");
    }
}

Producer 类如下:

public class Producer extends Thread {
    Tickets t = null;
    Producer(Tickets t) {
        this.t = t;
    }
    @Override
    public void run() {
        System.out.println("Producer start");
        while(t.pid < t.total) {
            t.put(10);
            try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace();}
        }
        System.out.println("Producer end");
    }
}

主函数:new 两个线程并启动,设置当前时间为 20:00

public class Main {
    public static void main(String[] args) {
        System.out.println("mainThread start");
        MyTime time = new MyTime(20, 0);
        time.printTime();
        System.out.println(" 当前时间");
        Tickets tickets = new Tickets(100, time);
        Producer pthread = new Producer(tickets);
        Custormer cthread = new Custormer(tickets);
        pthread.start();
        cthread.start();
        System.out.println("mainThread end");
    }
}

# 运行结果

运行结果如下图

请添加图片描述
请添加图片描述
请添加图片描述

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

cos 微信支付

微信支付

cos 支付宝

支付宝