当前位置:文档之家› 公交车管理系统

公交车管理系统

燕山大学课程设计说明书名称:操作系统OS题目:公交车上司机与售货员协调工作模拟班级:07级计算机开发小组:三剑客课题负责人:张浩课题组成员:张浩李康张晓玉姓名学号班级自评成绩张浩0701******** 07应用2班 A 李康0701******** 07软件3班 B 张晓玉0701******** 07软件3班 B 开发日期:2010年1月11日-15日1概述计算机操作系统是计算机系统中最不可缺少的,最常用的软件,也是核心的,最接近于计算机硬件的软件。

其特点是内容繁多,概念抽象,因此造成理解困难,掌握不易。

本软件的主要目的是通过直观的演示,使学生能够感性的明白掌握多道程序及其进程同步和互斥的程序设计的基本方法。

1.1基本功能利用多线程同步技术模拟公交车系统,实现司机与售票员的同步与互斥关系,即开车时不允许开门,开门时不允许开车,实现每个乘客一个线程同步互斥的上下车。

每站随即生成上下车人数,上下车线程实行,先下后上原则。

到终点站后,可以统计本次出车的载客人数。

1.2开发计划第一步,进行问题分析,确定需要解决的问题;第二步,进行整体构思与框架设计;第三步,查阅资料,分析所需要设计的程序算法;第四步,进行各种算法及各个细节编码的详细设计;第五步,进行代码调试,修改程序中的错误;第六步,整理总结书写报告,进行答辩。

1.3人员分工张浩:分析构架,核心代码编写;李康:用户界面设计,辅助代码编写,调试;张晓玉:功能测试、书写实验报告。

1.4 开发环境及开发工具本程序是以在windows XP下用Netbeans和jdk搭建的平台上,以Java 作为开发语言进行编写的。

使用的开发工具:netbeans.NetBeans 平台直接提供了应用程序的常见需求,如菜单、文档管理和设置。

“NetBeans”构建应用程序是指,仅提供NetBeans 平台尚不包含的应用程序部分,而不是从头开始编写应用程序。

在开发周期结束时,可以将应用程序与NetBeans 平台捆绑在一起,从而节省了很多时间和精力,并且构建的应用程序稳定可靠。

使用的开发语言:java.Java是一种简单的、面向对象的、分布式的、解释的、键壮的、安全的、结构的中立的、可移植的、性能很优异的多线程的、动态的语言。

其特点主要有:平台无关性、健壮性、面向对象、安全性、分布式。

1.5使用的基本概念和原理多道程序:用户所提交的作业都先存放在外存中并排成一个队列,成为“后备队列”;然后,由作业调度程序按一定的算法由后被队列中选择若干个作业调入内存,使它们共享CPU和系统中的各种资源。

进程:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位。

线程:操作系统用来调度、分派的最小单位。

同步和互斥:临界段:临界段对象通过提供所有线程必须共享的对象来控制线程。

只有拥有临界段对象的线程才可以访问保护资源(进行临界区操作)。

在另一个线程可以获取对象的访问权。

用户应用程序可能会使用临界对象来阻止两个线程同时访问共享的资源发文件等。

互斥量:互斥量的工作方式和临界段非常相似,其区别在于互斥量不公保护一个进程内的资源共享,而且还保护系统中进程之间的共享资源。

它是通过为互斥量提供一个“互斥量名”来进行进程间资源共享协调的。

事件:事件对象用于给线程传递信号,指示线程中特定的操作可以开始或结束。

除非线程已经收到了这个事件信号,否则它将一直处于挂起状态。

当事件对象进入其信号状态时,正在等待该事件的线程就可以开始执行。

例如,一个应用程序可以通过事件来通知线程它需要的数据已经准备好。

经常利用事件进行线程之间的通信。

信号量:信号量与互斥相似,但是互斥只允许在同一时刻一个线程访问它的数据,而信号量允许多个线程在同一时刻访问它的数据。

WIN32 不知道哪一个线程拥有信号量,它只保证信号量使用的资源计数正确的设置。

2需求分析协调司机和售票员以及乘客在运行与开关门以及上下车时的关系,实现同步互斥,避免发生不必要的冲突,节省了时间空间资源。

本程序显示上下车人数,并显示车上总人数,使车内人数不超过总座位数。

最终,利用统计功能,显示此次公交车运行的各种参数:车次、总站数、总载客数。

3总体设计基本的技术路线:面向对象;软件的总体结构:分为可视化界面以及后台数据执行;内部模块关系:司机类与售票员类同步互斥,上车类与下车类同步互斥;总体流程:停车-开门-下车-上车-关门-开车;需要创建的进程线程:主窗口线程、司机线程、售票员线程、上车乘客线程、下车乘客线程。

流程图如下:4详细设计Wait(),notify(),实现进程的等待和唤醒。

BusJFrame()创建主窗口,Driver()和Conductor()分别创建司机和售票员线程,PassengerOn()创建上车线程,PassengerOff()创建下称线程。

确定要设计的过程、构件、类、对象、函数和它们的参数,要给出具体的名称和参数及其解释。

由Driver类调用BusState类的stopCar()和runCar()方法,由Conductor 类调用BusState类的openDoor()和closeDoor()方法,实现同步互斥。

由PassengerOn类调用Seat类的takeOn()和hasOn()方法,由PassengerOff类调用Seat类的takeOff()和hasOff()方法,实现上下车线程的同步和互斥5编码设计5.1开发环境的设置和建立首先安装JDK,如下图:然后安装Netbeans,并关联JDK:5.2程序设计过程只需要注意的事项实现同步互斥的方法应成对出现,防止出现死锁状态;互斥信号应定义清晰,以用于互斥方法的实现;线程的创建和指针传递清晰明确,用于线程之间的交互。

5.3关键构件和插件的使用Netbeans的使用与一般编程软件接近,但是它包含了很多强大的插件,利用其中的插件我们可以简单的实现很多复杂的功能,例如在本次试验中恶我们程序的可视化窗口的建立就是利用如下组建实现的。

5.4主要程序的代码设计及注释BusState类主要源代码:public class BusState {public static boolean doorClosed=false;public static boolean busStopped=true;//获取输出框指针private static JTextArea bSay;public static void getBusSay(JTextArea b){bSay=b;}//获取输出框指针public synchronized void stopBus(){busStopped=true;bSay.setText("车已停");this.notify();}public synchronized void runBus() throws InterruptedException {while(!doorClosed){this.wait();busStopped=false;}}public synchronized void closeDoor(){doorClosed=true;bSay.setText("门已关");this.notify();}public synchronized void openDoor() throws InterruptedException {while(!busStopped){this.wait();doorClosed=false;}}}package ysu;import java.util.logging.Level;import java.util.logging.Logger;Conductor类的主要源代码:public class Conductor extends Thread{//获取主窗口指针private static BusJFrame bj;public static void getBusJFrame(BusJFrame b) {bj=b;}//获取BusState类的指针private static BusState bState;public static void getBusState(BusState b){bState=b;}//获得一个Driver进程类的指针private static Driver dr;public static void getDriver(Driver d){dr=d;}//用于创建On和Off类private void createOn(){Thread a=new PassengerOn();a.start();}private void createOff(){Thread b=new PassengerOff();b.start();}private boolean timeToQuit=false;private int station=0;public static boolean finish=false;public void run(){while(!timeToQuit){try {bState.openDoor();bj.busSay.setText("门已开");Thread.sleep(1000);bj.busSay.setText(null);bj.conductorSay.setText("请抓紧时间上下车");Thread.sleep(2000);bj.conductorSay.setText(null);bj.busSay.setText("开始上下车");Thread.sleep(2000);bj.busSay.setText(null);Seat.doorAvailable=true;if(Seat.willOn>(Seat.seatRemain+Seat.willOff)){Seat.canOn=Seat.seatRemain+Seat.willOff;}else{Seat.canOn=Seat.willOn;}//统计本次出车载客人次数Seat.totalPassenger=Seat.totalPassenger+Seat.canOn;//创建上下车乘客的进程for(int i=0;i<Seat.willOff;i++){createOff();}for(int i=0;i<Seat.canOn;i++){createOn();}if(Seat.canOn==0&&Seat.willOff==0){finish=true;}else{finish=false;//等待上下车完成}while(!finish){Thread.sleep(100);}if(Seat.canOn<Seat.willOn){bj.busSay.setText("很抱歉\n本车已满\n欢迎乘坐下班客车");Thread.sleep(2000);}Seat.doorAvailable=false;Seat.hasOn=0;//清零,防止出现累加Seat.hasOff=0;bj.busSay.setText("上下车完毕");bj.seatRemain.setText(""+Seat.seatRemain);bj.seatUsed.setText(""+Seat.seatUsed);station++;if(station>Seat.totalStation){timeToQuit=true;Driver.timeToQuit=true;break;}Thread.sleep(2000);bj.busSay.setText(null);bj.conductorSay.setText("关门了");Thread.sleep(2000);bj.conductorSay.setText(null);bState.closeDoor();Thread.sleep(1000);} catch (InterruptedException ex) {Logger.getLogger(Conductor.class.getName()).log(Level.SEVERE, null, ex);}try {Thread.sleep(200);} catch (InterruptedException ex) {Logger.getLogger(Conductor.class.getName()).log(Level.SEVERE, null, ex);}}bj.conductorSay.setText("终点站到了\n谢谢乘坐本车\n再见");bj.willOff.setText(""+0);bj.willOn.setText(""+0);BusJFrame.sumrizeAvailable=true;dr.stop();}}/** To change this template, choose Tools | Templates * and open the template in the editor.*/package ysu;import java.util.logging.Level;import java.util.logging.Logger;Driver类主要源代码:public class Driver extends Thread{//获取主窗口指针private static BusJFrame bj;public static void getBusJFrame(BusJFrame b){bj=b;}//获取BusState类的指针private static BusState bState;public static void getBusState(BusState b){bState=b;}//获取BusState类的指针public static boolean timeToQuit=false;public void run(){while(!timeToQuit){try {bState.runBus();Thread.sleep(1000);bj.driverSay.setText("出发");bj.nowNextSation.setText("下一站");bj.nextStation.setText("第"+(++Seat.nextStation)+"站");int a=(int)(Math.random()*10);//下车人数不能多于车上已有的人if(Seat.seatUsed<a){Seat.willOff=Seat.seatUsed;}else{Seat.willOff=a;}//提前创建下一站要下车的人数if(Seat.nextStation==Seat.totalStation){Seat.willOn=0;Seat.willOff=Seat.seatUsed;}else{Seat.willOn=(int)(Math.random()*10);//生成上车的人数}bj.willOff.setText(""+Seat.willOff);bj.willOn.setText(""+Seat.willOn);bj.busSay.setText(null);Thread.sleep(2000);bj.driverSay.setText(null);bj.busSay.setText("客车行驶中");Thread.sleep(3000);bj.busSay.setText(null);bj.driverSay.setText("到站了");bj.nowNextSation.setText("本站");Thread.sleep(1000);bj.driverSay.setText(null);bj.busSay.setText("车已停");Thread.sleep(1000);bState.stopBus();Thread.sleep(1000);} catch (InterruptedException ex) {Logger.getLogger(Driver.class.getName()).log(Level.SEVERE, null, ex);}}}}Seat类的主要源代码:/** To change this template, choose Tools | Templates* and open the template in the editor.*/package ysu;/**** @author Administrator*/public class Seat {public static int totalStation=4;public static int totalPassenger=0; public static int totalSeat=30;public static int stationName=10;public static int busName=30;public static int seatTotal=30;public static int seatRemain=30;public static int seatUsed=0;public static int willOff=0;public static int willOn=0;public static int canOn=0;public static int hasOn=0;public static int hasOff=0;public static int nextStation=0;public static boolean doorAvailable=true; public static void reset(){totalStation=12;totalPassenger=0;totalSeat=30;stationName=0;busName=30;seatTotal=30;seatRemain=30;seatUsed=0;willOff=0;willOn=0;canOn=0;hasOn=0;hasOff=0;nextStation=0;doorAvailable=true;}public synchronized void takeOn() throws InterruptedException {while(!doorAvailable||hasOff<willOff){this.wait();}doorAvailable=false;hasOn++;seatUsed++;seatRemain--;}public synchronized void takeOff() throws InterruptedException {while(!doorAvailable){this.wait();}doorAvailable=false;hasOff++;seatUsed--;seatRemain++;}public synchronized void hasOff(){doorAvailable=true;this.notifyAll();if(Seat.hasOff==Seat.willOff&&Seat.canOn==0){Conductor.finish=true;}}public synchronized void hasOn(){doorAvailable=true;this.notifyAll();if(Seat.hasOn==Seat.canOn){Conductor.finish=true;}}}PassengerOn类的主要源代码如下:/** To change this template, choose Tools | Templates * and open the template in the editor.*/package ysu;import java.util.logging.Level;import java.util.logging.Logger;/**** @author Administrator*/public class PassengerOn extends Thread{//获得Seat类的指针private static Seat seat;public static void getSeat(Seat s){seat=s;}//获取主窗口指针private static BusJFrame bj;public static void getBusJFrame(BusJFrame b){bj=b;}@Overridepublic void run(){try {Thread.sleep(100);} catch (InterruptedException ex) {Logger.getLogger(PassengerOn.class.getName()).log(Level.SEVERE, null, ex);}try {seat.takeOn();} catch (InterruptedException ex) {Logger.getLogger(PassengerOn.class.getName()).log(Level.SEVERE, null, ex);}bj.busSay.append("第"+Seat.hasOn+"人已经上车\n");bj.seatUsed.setText(""+Seat.seatUsed);bj.seatRemain.setText(""+Seat.seatRemain);bj.willOn.setText(""+(Seat.canOn-Seat.hasOn));bj.willOff.setText(""+(Seat.willOff-Seat.hasOff));try {Thread.sleep(2000);} catch (InterruptedException ex) {Logger.getLogger(PassengerOn.class.getName()).log(Level.SEVERE, null, ex);}seat.hasOn();}}PassengerOff类的主要源代码如下:/** To change this template, choose Tools | Templates * and open the template in the editor.*/package ysu;import java.util.logging.Level;import java.util.logging.Logger;/**** @author Administrator*/public class PassengerOff extends Thread{//获得Seat类的指针private static Seat seat;public static void getSeat(Seat s){seat=s;}//获取主窗口指针private static BusJFrame bj;public static void getBusJFrame(BusJFrame b){bj=b;}@Overridepublic void run(){try {Thread.sleep(100);} catch (InterruptedException ex) {Logger.getLogger(PassengerOff.class.getName()).log(Level.SEVERE, null, ex);}try {seat.takeOff();} catch (InterruptedException ex) {Logger.getLogger(PassengerOff.class.getName()).log(Level.SEVERE, null, ex);}bj.busSay.append("第"+Seat.hasOff+"人已经下车\n");bj.seatUsed.setText(""+Seat.seatUsed);bj.seatRemain.setText(""+Seat.seatRemain);bj.willOn.setText(""+(Seat.canOn-Seat.hasOn));bj.willOff.setText(""+(Seat.willOff-Seat.hasOff));try {Thread.sleep(2000);} catch (InterruptedException ex) {Logger.getLogger(PassengerOff.class.getName()).log(Level.SEVERE, null, ex);}seat.hasOff();}}5.5解决的技术难点、经常犯的错误理清司机与售票员之间的同步互斥关系和用于实现互斥的变量和放法,理清上下车乘客的同步互斥关系的变量与方法,确定司机、售票员、上下车乘客同步互斥变量;出现的错误有:互斥变量的使用,设计的位置不当,实现同步互斥的方法位置不当,最初的逻辑构架关系不对,以上错误经认真斟酌、校验,均已解决。

相关主题