模拟火车站售票的情形,有些显示问题。对多线程感兴趣的同志进来看看。

chenlinhaime1 2006-01-11 05:20:10
最近学了JAVA的多线程,想编一个模拟火车站售票的JAVA程序,但是总是在实时显示每个售票窗口的队列时有很大的错误(就是人多,需要排队的时候,每个顾客的ID总是显示相同),不知如何解决?望高手指教。

思路:火车站有许多售票窗口,有些开放,有些不开放。顾客进入火车站售票厅后,到某个售票先排队,排到了就办理业务,然后离去。
为了好控制,用按钮来增加顾客,由人自己来做添加。

代码如下:

/*模拟火车站售票的情形
分五个类:
SimulateRailwayStation:是具体运行类;
RailwayStation:火车站类
Agent类:代表火车站售票窗口类;
Customer类:顾客类;
List类:存储类
*/

import java.util.Date;
import java.awt.*;
import java.awt.event.*;
public class SimulateRailwayStation extends Frame implements ActionListener
{
protected static final int NUM_AGANTS=10;//表示火车站有10个售票窗口
protected static final int NUM_INITIAL_AGANTS=6;//表示目前正在售票的窗口6个
protected static final int BUSINESS_DELAY=6000;//表示每个窗口办理售票业务的时间
protected static final int MAX_TRAIN_NUM=10;//表示有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);addcus.addActionListener(this);
buttons.add(delcus);delcus.addActionListener(this);
buttons.add(addagent);addagent.addActionListener(this);
buttons.add(delagent);delagent.addActionListener(this);
addWindowListener(new WindowCloser());
setLayout(new BorderLayout());
add("North",railwaystation);
add("South",buttons);
setSize(500,200);
validate();
pack();show();
railwaystation.start();
}

public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==addcus)
{
railwaystation.generateCustomer();
}
else if(ae.getSource()==delcus)
{
//暂时未实现
}
else if(ae.getSource()==addagent)
{
//暂时未实现
}
else if(ae.getSource()==delagent)
{
//暂时未实现
}
}
public static void main(String[] args)
{
SimulateRailwayStation smlt=new SimulateRailwayStation();
}
}
...全文
399 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
orcd 2006-06-17
  • 打赏
  • 举报
回复
注释
wanglovec 2006-06-13
  • 打赏
  • 举报
回复
呵呵 怎么不写注释???

  • 打赏
  • 举报
回复
太长了,没法看。
proer9988 2006-02-15
  • 打赏
  • 举报
回复
up
chenlinhaime1 2006-01-11
  • 打赏
  • 举报
回复
class Customer
{
private Date created;//顾客开始排队的时间
private static int cId;//顾客ID,每个顾客都有唯一的ID,不能重复
private int customerwilling=0;//顾客购买票务的意愿,比如去哪里,班次等.
public Customer()
{
customerwilling=(int)(Math.random()*10+1);//顾客进入车站时就已经想好了买什么票,并且是火车站能够提供的.
created=new Date();
++cId;
System.out.print("new Customer"+cId+",");
}
public int getCustomerId()//获得顾客ID
{
return cId;
}
public int getCustomerWilling()//获得顾客买票意愿
{
return customerwilling;
}
public long getWaitTime(Date now)//获得顾客从进入火车站到离开窗口的时间
{
return now.getTime()-created.getTime();
}
}

class List //是一个队列容器,每个服务的窗口都有一个,顾客总是先进入这个队列容器后,再进行窗口的业务处理.
{
private int maxItems=100;//队列最大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;
}
public boolean isFull()//队列是否满了
{
return (numItems>=maxItems);
}
}
chenlinhaime1 2006-01-11
  • 打赏
  • 举报
回复
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)//new Agent
{
this.ID=ID;
}

public void start()//begin work
{
if(thread==null)
{
running=true;
thread =new Thread(this);
thread.start();
}
}

public void halt()//stop work
{
running=false;
}

public int getCIdOfHandling()//获得正在办理业务的顾客ID
{
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);
}
}
}
}
chenlinhaime1 2006-01-11
  • 打赏
  • 举报
回复
class RailwayStation extends Panel implements Runnable
{
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);
add("North",new Label(title));
}

public void start()//begin work
{
if(thread==null)
{
thread =new Thread(this);
thread.start();
}
}

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 updateDisplay()
{
int totalSize=0;
for(int i=0;i<numAgents;i++)
{
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 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)
{
int index=0;
for(int i=0;i<numAgents;i++)
{
if(agent[i].getCusCountOfQueue()<agent[index].getCusCountOfQueue())
{
index=i;
}
}
agent[index].joinNewCustomer(new Customer());
}
}

public void run()
{
while (true)
{
this.updateDisplay();
}
}
}

250

社区成员

发帖
与我相关
我的任务
社区描述
其他产品/厂家
社区管理员
  • 其他
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧