Java多線程實現(xiàn)模擬12306火車站售票系統(tǒng)
該系統(tǒng)一共涉及到3個類:
- 車票(Ticket)
- 12306系統(tǒng)(System12306)
- 售票窗口(Window)
車票類,涉及三個屬性:
- 起始站
- 終點站
- 票價
public class Ticket {
//起始站
private String startStation;
//終點站
private String destination;
/**POJO對象,它里面的基本類型最好使用包裝類
* 因為如果如果該類用來裝從數(shù)據(jù)庫中讀取的信息
* 如果讀取出null,那么基本類型是無法存null的,就會報錯*/
//票價
private Float price;
public Ticket(){}
public Ticket(String startStation, String destination, Float price) {
this.startStation = startStation;
this.destination = destination;
this.price = price;
}
//為了讓打印輸出時方便,我們重寫toString方法
public String toString() {
StringBuilder builder = new StringBuilder("[");
builder.append(this.startStation);
builder.append("--->");
builder.append(this.destination);
builder.append(":");
builder.append(this.price);
builder.append("]");
return builder.toString();
}
//get() and set()....
}
12306系統(tǒng),有一個屬性—>Vector集合,有一個方法—>獲取一張車票getTicket()
- 利用Vector集合存儲該系統(tǒng)所有的車票
- 利用Vector的線程安全特性,同一時間只能有一個線程操作該集合,保證安全
- 并且該系統(tǒng)應該是單例的
public class System12306 {
//設計一個單例模式
private System12306(){}
private static volatile System12306 sys;
public static System12306 getInstance(){
if (sys == null){
synchronized (System12306.class){
if(sys == null)
sys = new System12306();
}
}
return sys;
}
//屬性,用一個集合存票,我們使用線程安全的Vector,或者使用Stack,它繼承了Vector
private Vector<Ticket> tickets = new Vector<>();
private String[] starts = {"北京","天津","太原","運城","西安"};
private String[] ends = {"上海","武漢","蘇州","深圳","昆明","廣州"};
//當前系統(tǒng)創(chuàng)建后,就給tickets集合賦值
{
for(int i = 10;i<100;i++){//一共90張票
int r1 = (int)(Math.random()*starts.length);
int r2 = (int)(Math.random()*ends.length);
float price = r1*r2*5+140;
tickets.add(new Ticket(starts[r1],ends[r2],price));
}
}
//設計一個方法,從集合中獲取一張票
public Ticket getTicket(){
try {
return tickets.remove(0);
}catch (Exception e){
return null;
}
}
}
售票窗口類,有一個屬性—>窗口名稱,有一個方法—>出售車票sellTicket()
同一時間有多個窗口同時售票,該類實現(xiàn)了Runnable接口,達到多線程并發(fā)的效果
public class Window implements Runnable {
private String windowName;//窗口的名字
public Window(String windowName){
this.windowName = windowName;
}
@Override
public void run() {
this.sellTicket();
}
public void sellTicket(){
while (true){
System12306 sys = System12306.getInstance();
Ticket ticket = sys.getTicket();
if(ticket==null){
System.out.println("對不起,"+windowName+"窗口車票已售完...");
break;
}
System.out.println("從"+windowName+"窗口售出:"+ticket);
}
}
}
測試代碼:
public class TestMain {
public static void main(String[] args) {
Window win1 = new Window("北京西站");
Window win2 = new Window("運城北站");
Window win3 = new Window("太原南站");
new Thread(win1).start();
new Thread(win2).start();
new Thread(win3).start();
}
}
多線程并發(fā)執(zhí)行的效果:

到此這篇關于Java多線程實現(xiàn)模擬12306火車站售票系統(tǒng)的文章就介紹到這了,更多相關Java 模擬12306售票系統(tǒng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
解決Springboot全局異常處理與AOP日志處理中@AfterThrowing失效問題
這篇文章主要介紹了解決Springboot全局異常處理與AOP日志處理中@AfterThrowing失效問題,文中介紹了兩種失效場景,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-05-05
MyBatis-Plus通用枚舉自動關聯(lián)注入的實現(xiàn)
本文主要介紹了MyBatis-Plus通用枚舉自動關聯(lián)注入的實現(xiàn),解決了繁瑣的配置,讓 mybatis 優(yōu)雅的使用枚舉屬性,感興趣的可以一起來了解一下2021-06-06
分布式醫(yī)療掛號系統(tǒng)EasyExcel導入導出數(shù)據(jù)字典的使用
這篇文章主要為大家介紹了分布式醫(yī)療掛號系統(tǒng)EasyExcel導入導出數(shù)據(jù)字典的使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
詳解Springboot快速搭建跨域API接口的步驟(idea社區(qū)版2023.1.4+apache-maven-3.9.
這篇文章主要介紹了Springboot快速搭建跨域API接口(idea社區(qū)版2023.1.4+apache-maven-3.9.3-bin),本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下2023-07-07
springboot整合curator實現(xiàn)分布式鎖過程
這篇文章主要介紹了springboot整合curator實現(xiàn)分布式鎖過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05

