This article has been machine-translated from Chinese. The translation may contain inaccuracies or awkward phrasing. If in doubt, please refer to the original Chinese version.
Problem
Design and implement the ticket release function for a train ticket system:
A certain train reserves 100 seated tickets, and starts releasing tickets at 8 PM every evening, randomly releasing 10 tickets every 30 minutes.
Simple simulation of ticket release and purchase: Display the customer who grabbed a certain ticket number at a certain time. Simulate server ticket release and client ticket purchase: The server displays information about which tickets were released at what time and which ticket was sold at what time; the client displays information about which ticket was purchased at what time.
Approach and Code
The server is the Producer class, the client is the Customer class, both extending Thread for multithreading. There is also a Tickets class representing remaining tickets and a MyTime class representing time.
Source code download: cos_javatest2
MyTime class: The passM function simulates the passage of minute minutes.
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 class:
This is the key part. total is the total number of reserved tickets (100), time is the current time, cid is the sales counter (1 means 1 ticket sold), pid is the stock counter (10 means 10 tickets stocked), available indicates whether tickets are available, serving as a synchronization flag. All are initialized to 0. The Tickets object is shared between the two threads.
import java.util.List;
import java.util.Stack;
public class Tickets {
int total; // Total tickets
MyTime time; // Current time
int cid; // Sales counter
int pid; // Stock counter
boolean available; // Whether tickets are 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) { // Synchronized method to add tickets
if(available) {
System.out.println("Not time to stock tickets yet, please wait.");
try {wait();} catch (InterruptedException e) {e.printStackTrace();}
}
pid += num;
time.printTime();
System.out.printf("Producer stocked %d tickets, current remaining: %d\n", num, pid-cid);
available = true;
notify();
}
public synchronized void sell() { // Synchronized method to sell tickets
if(!available) {
System.out.printf("No tickets available, please wait @Customer %d\n", cid);
try {wait();} catch (InterruptedException e) {e.printStackTrace();}
}
time.printTime();
if(available && cid < pid) {
System.out.printf("Customer %d purchased ticket %d\n", ++cid, cid);
}
if(cid == pid) available = false;
notify();
}
}
Customer class: Extends Thread with overridden run method. Assumes one customer buys a ticket every 3 minutes. Shares the Tickets object with the Producer class, so internal methods of Tickets must be synchronized.
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 class:
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");
}
}
Main function: Creates two threads and starts them, setting the current time to 20
.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(" Current time");
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");
}
}
Execution Results
The execution results are shown in the figures below:



喜欢的话,留下你的评论吧~