⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulaterailwaystation.java

📁 用JAVA开发的售票系统希望能通过
💻 JAVA
字号:
/*
项目:用多线程设计一个模拟火车站售票大厅的工作情形。
问题描述:火车站有许多售票窗口,有些开放,有些不开放。顾客进入火车站售票厅后,到某个售票窗口排队等候,排到了就办理业务,然后离去。如图2.1所示。
*/

/*
*共有五个类:
*SimulateRailwayStation:具体运行主类;
*RailwayStation:火车站售票大厅类
*Agent类:代表火车站售票窗口类;
*Customer类:顾客类;
*List类:存储类
*/

import java.util.Date;
import java.awt.*;
import java.awt.event.*;
public class SimulateRailwayStation extends Frame implements ActionListener
{
  //预设火车站售票大厅有10个售票窗口
  protected static final int       NUM_AGANTS=10;
  //预设目前正在售票的窗口为6个
  protected static final int       NUM_INITIAL_AGANTS=6;
  //设置每个窗口办理售票业务的时间
  protected static final int       BUSINESS_DELAY=6000;
  //设置有10辆火车的座位可以出售
  protected static final int       MAX_TRAIN_NUM=10;
  //设置每个窗口从一个顾客完成到下一个顾客开始的时间间隔
  protected static final int       MAX_NO_CUSTOMERS=200;
  //定义按钮,手动添加顾客。
  private Button                   addcus=new Button("添加顾客");
  //定义按钮,模拟顾客自己离开
  private Button                   delcus=new Button("顾客离去");
  //定义按钮,增加售票窗口
  private Button                   addagent=new Button("增加售票窗口");
  //定义按钮,关闭售票窗口
  private Button                   delagent=new Button("关闭售票窗口");
  //10辆火车班次的信息
  protected static String[]        train_num={"南京->北京,46次","南京->上海,34次","南京->福州,231次","南京->杭州,65次","南京->武汉,112次","南京->成都,77次","南京->天津,21次","南京->徐州,134次","南京->乌鲁目齐,335次","南京->合肥,456次"};
  //与上面的信息对应的每辆火车的票务信息
  protected static int[]           tickets={50,70,50,50,50,120,60,100,50,50};
  //实例化火车站售票大厅类
  private RailwayStation           railwaystation=new RailwayStation();

  //建立窗体适配器,能关闭窗口
  private class WindowCloser extends WindowAdapter
  {
    public void windowClosing(WindowEvent we)
    {
      railwaystation.stop();
      System.exit(0);
     }
   }


   //构造方法,完成界面初始化
  public SimulateRailwayStation()
  {
    super("Simulation RailwayStation");
    //设置面板
    Panel buttons=new Panel();
    buttons.setLayout(new FlowLayout());
    //在面板中添加按钮
    buttons.add(addcus);
    buttons.add(delcus);
    buttons.add(addagent);
    buttons.add(delagent);
    //对按钮设置监听
    addcus.addActionListener(this);
    delcus.addActionListener(this);
    addagent.addActionListener(this);
    delagent.addActionListener(this);
    //对窗体适配器设置监听
    addWindowListener(new WindowCloser());
    setLayout(new BorderLayout());
    add("North",railwaystation);
    add("South",buttons);
    setSize(500,200);
    validate();
    pack();
    show();
    //调用火车站售票大厅类的start()方法,开始售票工作
    railwaystation.start();
  }


  public void actionPerformed(ActionEvent ae)
  {
    if(ae.getSource()==addcus)
     {
      //新增顾客	
      railwaystation.generateCustomer();
     }
    else if(ae.getSource()==delcus)
     {
          
     }
   else if(ae.getSource()==addagent)
     {
       //增加售票窗口
        railwaystation.addAgent();
     }
   else if(ae.getSource()==delagent)
     {
     	//关闭服务窗口
       railwaystation.retireAgent();
     }
  }
  
  public static void main(String[] args) 
   {
    SimulateRailwayStation smlt=new SimulateRailwayStation();
   }        
}

/* 火车站售票大厅类 */
class RailwayStation extends Panel implements Runnable
{
 //定义售票窗口数组Agent[]
 protected Agent[] agent=new Agent[SimulateRailwayStation.NUM_AGANTS];
 protected Label[] labelAgent=new Label[SimulateRailwayStation.NUM_AGANTS];
 protected Label   labelQueue=new Label("正在等待的顾客数:0");
 protected Label   labelServed=new Label("已经服务的顾客数:0");
 //定义可以进行售票服务的窗口
 protected int     numAgents=SimulateRailwayStation.NUM_INITIAL_AGANTS;
 //定义存放已服务过的顾客数
 public static int numCustomerServered=0;
 private Thread    thread=null;
        
 public RailwayStation()
 {
    setup("各窗口实时状态显示:");
 }

 //显示各售票窗口的实时工作状态
 private void setup(String title)
 {
  //定义售票窗口的工作状态面板
  Panel agentPanel=new Panel();
  agentPanel.setLayout(new GridLayout(SimulateRailwayStation.NUM_AGANTS,1));
  //各售票窗口的工作状态
  for(int i=0;i<SimulateRailwayStation.NUM_AGANTS;i++)
  {
   if(i<numAgents)
   {
    labelAgent[i]=new Label("窗口"+(i+1)+":空闲中...");
    agentPanel.add(labelAgent[i]);
    //实例化售票窗口
    agent[i]=new Agent(i);
    //售票窗口开始售票服务
    agent[i].start();
   }
   else
   {
    labelAgent[i]=new Label("窗口"+(i+1)+":暂停服务!");
    agentPanel.add(labelAgent[i]);
   }                        
  }
  //定义顾客候票情况面板
  Panel otherPanel=new Panel();
  otherPanel.setLayout(new GridLayout(2,1));
  otherPanel.add(labelQueue);
  otherPanel.add(labelServed);
  setLayout(new BorderLayout());
  //显示各售票窗口的工作状态安排在下部
  add("South",agentPanel);
  //显示顾客候票状况安排在中部
  add("Center",otherPanel);
  //显示调用本方法 setup()的参数安排在上部
  add("North",new Label(title));
 }
        
 //开始工作
 public void start()
 {
   if(thread==null)
    {
      thread =new Thread(this);
      //启动线程
      thread.start();
    }
 }
 
  //线程,调用显示实时售票状况的updateDisplay()方法       
 public void run()
 {
  while (true)
  {
   this.updateDisplay();
  }
 }
 
 //实时处理售票的状况
 public void updateDisplay()
 {
  //定义在本窗口等候的顾客数
  int totalSize=0;
  //对可以服务的窗口进行循环
  for(int i=0;i<numAgents;i++)
  {
  	//getCIdOfHandling()方法为正在办理业务的顾客编号
   if(agent[i].getCIdOfHandling()!=0)
   {
   	//统计在本窗口等候的顾客数
    totalSize+=agent[i].getCusCountOfQueue();
    String s="窗口"+(i+1)+":正在办理顾客"+agent[i].getCIdOfHandling()+"业务";
    //显示在本窗口等候的顾客数
    if(agent[i].getCusCountOfQueue()>0)
      labelAgent[i].setText(s+"["+agent[i].getCusOfQueue()+"正在等待]");
    else
      labelAgent[i].setText(s);
   }
   else
   {
    labelAgent[i].setText("窗口"+(i+1)+":空闲中...");
   }
  }
  for(int i=numAgents;i<SimulateRailwayStation.NUM_AGANTS;i++)
     labelAgent[i].setText("窗口"+(i+1)+":暂停服务!");
  labelQueue.setText("正在等待的顾客数:"+totalSize);
  labelServed.setText("已经服务的顾客数:"+numCustomerServered);
 }
        
 //火车站售票窗口关闭
 public void stop()
 {
  thread=null;
  for(int i=0;i<numAgents;i++)
  {
  	//停止售票服务
    agent[i].halt();
  }
 }
        
 //添加窗口
 public void addAgent()
 {
  if(numAgents<SimulateRailwayStation.NUM_AGANTS)
  {
   agent[numAgents]=new Agent(numAgents);
   agent[numAgents].start();
   numAgents++;
  }
 }
        
 //关闭窗口,该方法暂时没有使用
 public void retireAgent()
 {
  if(numAgents>1)
  {
    agent[numAgents-1].halt();
    numAgents--;
  }
 }
        
        
 //接待顾客的方法
 public void generateCustomer()
 {
  //所有工作窗口的队列中,至少有一个顾客在排队时为真.
  boolean allAgentQueueHasOne=true;
  /* 如果所有正在工作窗口的队列中至少有一个顾客在排队,
     就把新顾客添加到队列最少的那个队.
     否则,就把顾客添加到没有业务处理的窗口中.
  */
   //对可以服务的窗口进行循环
  for(int i=0;i<numAgents;i++)
  {
  	//如果本窗口队列中没有顾客
   if(agent[i].getCusCountOfQueue()==0 && agent[i].getCIdOfHandling()==0)
   {
   	//添加新顾客
    agent[i].joinNewCustomer(new Customer());
    allAgentQueueHasOne=false;
    break;
   }
  }
  //如果所有工作窗口都有顾客在等候
  if(allAgentQueueHasOne)
  {
   //定义变量index存放最少等候顾客数的窗口编号
   int index=0;
   //对可以服务的窗口进行循环
   for(int i=0;i<numAgents;i++)
   {
    if(agent[i].getCusCountOfQueue()<agent[index].getCusCountOfQueue())
    {
      index=i;
    }
   }
   //往最少顾客的窗口加新顾客
   agent[index].joinNewCustomer(new Customer());        
   }
  }
 

}

/*火车站售票窗口类 */
class Agent extends Panel implements Runnable
{
 //窗口开放标志
 private boolean   running =false;
 private int       ID=-1;
 private int       numCustomers=0;
 private int       handlingCId=0;
 //该窗口中排队的顾客
 private List      customersofqueue=new List();
 //该窗口中已办理的顾客
 private List      customersofhandled=new List();
 private Label     labelHandling=new Label();
 private Label     labelThisQueue=new Label();
 private Thread    thread=null;
        
  //构造方法,定义售票窗口编号
 public Agent(int ID)
 {
   this.ID=ID;
 }
  
  //  售票窗口开始售票服务    
 public void start()
 {
  if(thread==null)
  {
   running=true;
   thread =new Thread(this);
    //启动线程
   thread.start();
  }
 }
        
 //停止售票服务 
 public void halt()
 {
   running=false;
 }
 
 //获得正在办理业务的顾客ID
 public int getCIdOfHandling()
 {
   return handlingCId;
 }
 
 //从本窗口的队列中获得将要服务的顾客		
 public Customer requestCustomerFor()
 {
  if(customersofqueue.getSize()>0)
  {
   Customer c=(Customer)customersofqueue.get(0);
   customersofqueue.delete(0);
   return c;        
  }
  else
  {
   return null;
  }
 }
        
 //本窗口已办理业务的顾客数
 public int getCusCountOfHandled()
 {
  return numCustomers;
 }

 //本窗口已办理业务的顾客列表
 public String getCusOfHandled()
 {
  if(customersofhandled.getSize()>0)
  {
   StringBuffer sbuf=new StringBuffer();
   sbuf.append("顾客");
   for(int i=0;i<customersofhandled.getSize();i++)
   {
    sbuf.append(((Customer)customersofhandled.get(i)).getCustomerId());
    if(i!=customersofhandled.getSize()-1)
       sbuf.append(",");
   }
   return sbuf.toString();
  }
  else
  {
   return new String("");        
  }
 }

  //在窗口的队列中添加新顾客      
 public synchronized void joinNewCustomer(Customer c) 
 {
  if(!customersofqueue.isFull())
  {
   customersofqueue.add(c);
   System.out.println("join to agent"+(this.ID+1));
  }
 }
        
  //获得本窗口的队列中的顾客列表
 public synchronized String getCusOfQueue() 
 {
  if(customersofqueue.getSize()>0)
  {
   StringBuffer sbuf=new StringBuffer();
   sbuf.append("Customer");
   for(int i=0;i<customersofqueue.getSize();i++)
   {
    sbuf.append(((Customer)customersofqueue.get(i)).getCustomerId());
    if(i!=customersofqueue.getSize()-1)
       sbuf.append(",");
   }
   return sbuf.toString();
  }
  else
  {
   return new String("");        
  }
 }
        
 //获得本窗口的队列中的顾客数
 public int getCusCountOfQueue()
 {
  return customersofqueue.getSize();
 }

 //本窗口队列中的顾客未办理业务离去	
 public void CustomerLeft()
 {
  if(customersofqueue.getSize()>0)
     customersofqueue.delete(customersofqueue.getSize()-1);
 }
        
 //顾客办理完业务离去
 public void releaseCustomer(Customer c)
 {
  numCustomers++;
  customersofhandled.add(c);
 }
        
 //本窗口在不断的处理业务
 public void run()
 {
  while (running)
  {
   try
   {
    thread.sleep((int)(Math.random()*SimulateRailwayStation.MAX_NO_CUSTOMERS)+1000);
    Customer customer=requestCustomerFor();//获得服务的顾客
    if(customer!=null)
    {
     handlingCId=customer.getCustomerId();//获得顾客ID
     //办理业务时间:主要是询问等
	 thread.sleep((int)(Math.random()*SimulateRailwayStation.BUSINESS_DELAY)/2);
     synchronized(this)
     {                                        
      //检索对应的票务信息
	  for(int i=0;i<SimulateRailwayStation.train_num.length;i++)
      {
       if(customer.getCustomerWilling()==i+1)
          SimulateRailwayStation.tickets[i]--;//对应票数减一
      }
     }
     //办理业务时间:打印票、交钱等
	 thread.sleep((int)(Math.random()*SimulateRailwayStation.BUSINESS_DELAY)/2);
     releaseCustomer(customer);//顾客办理后离开。
     RailwayStation.numCustomerServered+=1;//服务顾客数+1
    }
    else
    {
     handlingCId=0;
    }
   }
   catch(InterruptedException ie)
   {
    System.out.println("Teller Exception: "+ie);
   }
  }
 }
}

/*顾客类*/
class Customer
{
 //顾客开始排队的时间
 private Date         created;
 //顾客ID,每个顾客都有唯一的ID,不能重复
 private static int   cId;
 //顾客购买票务的意愿,比如去哪里,班次等.
 private int          customerwilling=0;
 
 public Customer()
 {
  //顾客进入车站时就已经想好了买什么票,并且是火车站能够提供的.
  customerwilling=(int)(Math.random()*10+1);
  created=new Date();
  ++cId;
  System.out.print("new Customer"+cId+",");
 }
  
  //获得顾客ID
 public int getCustomerId()
 {
  return cId;
 }

   //获得顾客买票意愿
 public int getCustomerWilling()
 {
   return customerwilling;
 }

 //获得顾客从进入火车站到离开窗口的时间
 public long getWaitTime(Date now)
 {
   return now.getTime()-created.getTime();
 }
}

/*构造一个队列容器,每个服务的窗口都有一个,
顾客总是先进入这个队列容器后,再进行窗口的业务处理.*/
class List
{
	//定义队列最大容量:100人
 private int        maxItems=100;
 private int        numItems=0;
 private int        ID=-1;
 private Object[]   list=null;
 
 public List()
 {
   list=new Object[maxItems];
 }

 public List(int maxItems)
 {
  this.maxItems=maxItems;
  list=new Object[this.maxItems];
 }

  //在队列中增加顾客
 public void add(Object obj)
 {
  list[numItems++]=obj;
 }

  //在有人离开队列
 public void delete(int pos)
 {
  for(int i=pos+1;i<numItems;i++)
  {
    list[i-1]=list[i];
  }
  numItems--;
 }

 //得到队列中指定的人
 public Object get(int pos)
 {
  return list[pos];
 }

 //队列中的人数
 public int getSize()
 {
  return numItems;
 }

 //队列是否满了(超过100人)
 public boolean isFull()
 {
  return (numItems>=maxItems);
 }
}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -