java多线程模拟购买火车票
-
本次做的是一个火车票的售卖模拟,不管用户是在窗口还是APP上购买,必然不可能买到同一张票这也就是说一张票的售卖必然是一个线程在操作的,所以,我们在写代码是也要注意这一点
-
首先我们要进行分析 我们需要几个类来完成我们的代码 根据java面向对象编程的思想,我们可以代入现实生活中的场景
买票–>车站–>窗口–>购票
通过上述的流程我们可以大概的先分为三个类 车票类 车站类(或者系统类,统一储存票的地方)
而其中,我们知道火车站或者APP上,每个用户在任何时间都能够购票,所以买票是可以很多人一起进行的,而窗口也是如此,同样的时间,有可能5个窗口都在售票,但是窗口出票是单线程的,而售票功能则是多线程在进行的,所以我们将窗口类设置为多线程的实现类 -
类的分析完毕,开始编写代码
-
车票类-->起始站-->终点站-->价格 这是车票固有的属性
-
系统类-->统一储存的车票(可以用集合来储存)-->出票方法(从集合中减少一张票,售出)
-
窗口类-->继承Thread并重写run()方法-->售票方法(调用系统中的出票方法)
车票类
package Thread.train_tickets;public class Ticket {private String start;private String end;private Float price;public Ticket(){}public Ticket(String start, String end, Float price){this.start = start;this.end = end;this.price = price;}public String getStart() {return start;}public void setStart(String start) {this.start = start;}public String getEnd() {return end;}public void setEnd(String end) {this.end = end;}public Float getPrice() {return price;}public void setPrice(Float price) {this.price = price;}@Overridepublic String toString() {return "Ticket{" +"start='" + start + '\'' +", end='" + end + '\'' +", price=" + price +'}';}
}
系统类
package Thread.train_tickets;import java.util.List;
import java.util.Vector;public class System12306 {//单例模式 事先创建对象private static System12306 sys = new System12306();private List<Ticket> vector = new Vector<Ticket>();//在类加载的时候向集合中添加元素{for(int i=0;i<50;i++){vector.add(new Ticket("北京"+i,"深圳"+i,i*25/10F));}}private System12306(){}public static System12306 getSystem12306(){return sys;}//出票方法public Ticket sellTicket(){try{return vector.remove(0);//直接从集合中删除第一个元素}catch(IndexOutOfBoundsException e){return null;//如果出现了异常,证明集合已经没有元素,直接返回null即可}}
}
窗口类
package Thread.train_tickets;public class Window extends Thread{private String windowName;public Window(String windowName) {this.windowName = windowName;}public String getWindowName() {return windowName;}public void setWindowName(String windowName) {this.windowName = windowName;}public void run(){this.sellTicket();}//系统售票方法public void sellTicket(){System12306 sys = System12306.getSystem12306();while(true){Ticket t = sys.sellTicket();//从集合中出一张票if(t!=null){//非空则出票成功System.out.println("从"+this.windowName+"售出一张"+t);}else{System.out.println("票已售光");break;}}}
}
最后测试执行
package Thread.train_tickets;public class Test {public static void main(String[] args) {Window win1 = new Window("北京东站");Window win2 = new Window("北京西站");Window win3 = new Window("北京南站");// 注意不要调用run()方法win1.start();win2.start();win3.start();}
}
运行结果
因为出票必须是保证线程安全的,同一时间只能有一张票被操作,所以集合上我们选择自带线程安全的Vector集合,同时在系统类加载时我们就需要集合中有数据,所以我们可以用代码块(在类加载的时候就执行)来进行集合中的数据添加,同时我们要保证每个窗口出的票是基于同一个系统对象,所以我们需要用单例模式来进行设计系统类
由于我是一名学生,所以写的代码难免会有很多不足之处,也希望各位能够多多指出来,非常感谢