能够同时进出车 可直接运行的基于Java多线程的停车场管理系统( 二 )


类(实现Car接口的类):
package BigTest;public class DerivedCar extends Car {DerivedCar(){}@Overrideprotected String initBrand() { return "宝马"; }@Overrideprotected String initModel() { return "轿车"; }public DerivedCar(String number) {super(number);}}
类(实现Car接口的类):
package BigTest;public class DerivedCar1 extendsCar {DerivedCar1(){}@Overrideprotected String initBrand() {return "奔驰";}@Overrideprotected String initModel() {return "轿车";}public DerivedCar1(String number) { super(number); }}
类(实现Car接口的类):
package BigTest;public class DerivedCar2 extends Car {DerivedCar2(){}@Overrideprotected String initBrand() {return "比亚迪";}@Overrideprotected String initModel() { return "SUV"; }public DerivedCar2(String number) {super(number);}}
类:
package BigTest;import java.io.Serializable;import java.text.SimpleDateFormat;import java.util.HashMap;public class Transaction implements Serializable {//订单号:暂时使用车牌号存储,或按车辆进入的顺序生成订单号private String orderNumber;//进车库时间private double enterTime;//出车库时间private double exitTime;//用于存储格式化之后的进入车库的时间private String enterStime;//用于存储格式化之后的退出车库的时间private String exitStime;//令一秒钟0.0025元,即一分钟0.15元,一小时9元(不足一小时按一小时算)//使用出库时间-出库时间算出毫秒的时间差,(时间差/1000)/3600即可得出小时差private int numCost;private Car car;//获取订单信息public String getOrderNumber() {return orderNumber;}//获取订单信息内的Car类public Car getCar() {return car;}public double getEnterTime() {return enterTime;}public double getExitTime() {return exitTime;}public String getEnterStime() {return enterStime;}public String getExitStime() {return exitStime;}public int getNumCost() {return numCost;}public void setOrderNumber(String orderNumber) {this.orderNumber = orderNumber;}private static HashMap sum = new HashMap<>();//使用多态传入Car类型的车辆Transaction(String orderNumber,Car car){this.orderNumber = orderNumber;this.car = car;enterTime = System.currentTimeMillis();//格式化时间SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");enterStime = formatter.format(enterTime);}public String exitWay(){//获取当前时间exitTime = System.currentTimeMillis();//格式化时间SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");exitStime = formatter.format(exitTime);//总收费numCost =(int) ((((exitTime - enterTime)/1000.0)/3600.0)*9.0);String flag = ("订单号:" + orderNumber + " 入库时间:" + enterStime + " 出库时间:" + exitStime + " " + car.toString() + " 总花费:" + numCost);return flag;}public String toString(){String flag = ("订单号:" + orderNumber + " 入库时间:" + enterStime + " 出库时间:" + exitStime + " " + car.toString() + " 总花费:" + numCost);return flag;}//判断汽车是否符合要求(判断是否是系统已存在的车型及品牌)public static Car Judging(String model,String brand,String orderNumber){sum.put(0,"宝马轿车");sum.put(1,"奔驰轿车");sum.put(2,"比亚迪SUV");int j = 0;String judg = brand+model;//遍历HashMapfor(int i: sum.keySet()){if(sum.get(i).equals(judg)){j = i;break;}else{j = -1;}}Car c1;//根据输出的值来创建carif(j == 0 ){c1 = new DerivedCar(orderNumber);}else if(j == 1){c1 = new DerivedCar1(orderNumber);}else if(j == 2){c1 = new DerivedCar2(orderNumber);}else{c1 = null;}return c1;}}
Park类:
package BigTest;import java.io.*;import java.util.ArrayList;import java.util.List;import java.util.Scanner;import java.util.concurrent.CopyOnWriteArrayList;import java.util.concurrent.atomic.AtomicReference;public class Park implements Serializable {/*** 利用AtomicReference*/private static final AtomicReference INSTANCE = new AtomicReference();/*** 私有化*//*** 用CAS确保线程安全*/public static final Park getInstance() {for (; ; ) {Park current = INSTANCE.get();if (current != null) {return current;}current = new Park();if (INSTANCE.compareAndSet(null, current)) {return current;}}}public Park() {this(6);}private Park(int maxSize) {this.maxSize = maxSize;}//表示停车场的车辆个数private static int maxSize;//表示当前停车场占用的位置private static int top = 0;//默认初始化的订单号(如果有文件存储订单号的话,则会使用文件存储的订单号,继续累加下去)private static int order = 1;//内部类使用Runnable接口,使用两个内部类就可以模拟出一个入口一个出口了//这样在入口进车的同时还可以让车子出库 。//出库的内部类private class Exit implements Runnable {@Overridepublic void run() {exit(exitCars);}}//入库的内部类private class Enter implements Runnable {@Overridepublic void run() {enter();}}//使用CopyOnWriteArrayList来确保容器线程的安全,同时使出库的车与入库的车分开存放,在出入库操作时尽量避免同时而操作造成越界//存储进入车库的车private static List lists = new CopyOnWriteArrayList();//存储想要出库的车private static List exitCars = new CopyOnWriteArrayList();//存储想要入库的车private static List enterCars = new CopyOnWriteArrayList();//暂时存储用户需要入库的车,待用户总体输入完毕之后,便执行多线程private void enter(Car car) {//获取当前订单号String orderNumber = String.valueOf(order);//主菜单中已判定传入的car不为null了,因此可以直接添加enterCars.add(new Transaction(orderNumber, car));order++;}//此为出库线程run时执行的方法private void enter() {//遍历enterCars容器,获取要出库的车的信息for (Transaction transaction : enterCars) {if (top == maxSize) {System.out.println("车位不足" + "车牌号为:" + transaction.getOrderNumber() + "入库失败失败");} else {boolean flag = true;//遍历车库内的信息,判断是否已存在该车牌for (Transaction transaction1 : lists) {if (transaction1.getCar().getNumber().equals(transaction.getCar().getNumber())) {System.out.println(transaction.getOrderNumber() + "车牌已经存在,汽车入库失败");flag = false;break;}}//如果车库内不存在该车牌信息则执行以下操作if (flag) {//将该车辆信息存入车库内(lists存放入库的车)lists.add(transaction);//从候车区删除已经入库的车enterCars.remove(transaction);//设定入库时间为1stry {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(transaction.getCar().getNumber() + "入库成功");top += 1;}}}}//为菜单提供一个方法供菜单使用private void enter(Car car, Park p1) {p1.enter(car);}//此方法为多线程调用的出库方法private void exit(List exitCars) {for (Transaction transaction : exitCars) {System.out.println(transaction.getCar().getNumber() + "出库成功");System.out.println(transaction.exitWay());try {//出库之后就将出库的信息序列化SerializableTest.serializecar(transaction);} catch (IOException e) {e.printStackTrace();}//将其出库候车区移除exitCars.remove(transaction);try {Thread.currentThread().sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}//用于用户暂时存储要出库的车,等用户输入完毕后调用线程再执行出库private void exit(String... orderNumbers) {for (String orderNumber : orderNumbers) {for (Transaction transaction : lists) {//如果车牌号存在,则将其加入候车区,等待线程执行出库操作if (orderNumber.equals(transaction.getCar().getNumber())) {exitCars.add(transaction);//从车库中移除该信息lists.remove(transaction);top--;break;}}}}//打印菜单public void Menu() {int chose = -2;//对车库进行初始化//***********提取文件内已存车的信息************ArrayList arr = new ArrayList();try {arr = SerializableTest.deserializecar1();} catch (Exception e) {e.printStackTrace();}System.out.println("车库内已有:" + arr.size() + "辆车");//将提取出来的Object类转换成Transaction类,这样才能够进行出库操作for (int j = 0; j