黑马程序员_交通灯管理系统笔记

------- android培训java培训、期待与您交流! ----------

该视频总共包括了以下部分。

    01. 圆了程序员梦却失去了心爱女友漫谈
    02. 面试题来源与情景介绍
    03. 程序员网校与程序员职业生涯分析
    04. 交通灯管理系统的业务和需求分析
    05. 精通面向对象的分析和设计的秘诀
    06. 交通灯控制系统的类的实现细节分析
    07. 编写Road类中模拟汽车上路的代码
    08. 定义器与Road类中模拟汽车穿过路口
    09. 编写表示交通灯的Lamp类的代码
    10. 编写交通灯控制器的类和总成测试
    11. 漫谈面试与高薪求职之路
    12. 源代码与PPT
张老师给我们进行了详细的分析。首先要明确目的,根据要求进行分析,全部思路明确之后再进行代码的敲写。这样就会变得很简单。

系统要求:

异步随机生成按照各个路线行驶的车辆。
例如:
    由南向而来去往北向的车辆 ---- 直行车辆
    由西向而来去往南向的车辆 ---- 右转车辆
    由东向而来去往南向的车辆 ---- 左转车辆
       。。。

信号灯忽略黄灯,只考虑红灯和绿灯。

应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。

具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。

注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。

  每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。

  随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。

  不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
看完要求就需要开始分析。
总共有12条路线
为了统一编程模型,可以假设每条路线都有一个红绿灯对其进行控制,右转弯的可以假设称为常绿状态,另外,其他的8条线路是两两成对的,为4组,所以,程序只需要考虑途中标注了数字号的4条路线的控制灯的切换顺序,这四条路线相反方向的路线的控制灯跟随这4条路线切换,不必另外考虑。
视频里程序的分析:
MainClass

String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
/* 解读: 这里使用String类型传递给Road作为构造函数参数,视频里类型的确定有一个步进过程,张老师在讲解之初使用的是Road对象作为参数,之后发现无法使用自身对象作为构造函数参数传递给自己,因为使用构造函数的时候显然对象还没建立,也就是说构造函数里不能使用自身对象作为参数。使用后期改用String类传递名称*/

for(int i=0;i<directions.length;i++){
new Road(directions[i]);
}
/* 解读: 产生Road对象,也就是各个方向的路,本质上是各个方向上的车,功能是*/

new LampController();
/* 解读: 产生整个交通灯系统,功能是*/

Road类

private List<String> vechicles = new ArrayList<String>();
/* 解读: 建立用于存储车辆的集合*/

private String name =null;
/* 解读: 用于想Road类传递路线参数的的临时变量*/

public Road(String name){
/* 解读: Road类的构造函数*/

this.name = name;

//模拟车辆不断随机上路的过程
ExecutorService pool = Executors.newSingleThreadExecutor();
/* 解读: 建立单线程的线程池对象pool,即每次调用Road构造函数都会产生一个ExecutorService,用于在下一步中建立新线程,也就是保证每条线路上的车都对外的隔离,完全是根据自己线路上的红绿灯情况而自动运行*/

pool.execute(new Runnable(){
public void run(){
for(int i=1;i<1000;i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
/* 解读: 控制当前方向上每次停顿1~10秒再产生下一辆车 */

} catch (InterruptedException e) {
e.printStackTrace();
/* 解读: 当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。*/

}
vechicles.add(Road.this.name + "_" + i);
/* 解读: 为车辆编号,格式为:当前路线 + 序号 */
}
}

});
/* 解读: void execute(Runnable command) 方法是ExecutorServic自Executor接口中继承的方法,用于建立新线程 */

//每隔一秒检查对应的灯是否为绿,是则放行一辆车
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
/* 解读: static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。 */

timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
if(vechicles.size()>0){
boolean lighted = Lamp.valueOf(Road.this.name).isLighted();
if(lighted){
System.out.println(vechicles.remove(0) + " is traversing !");
}
}

}
},
1,
1,
TimeUnit.SECONDS);
/* 解读: ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。 这里的设置为1s后开始运行线程,并且每隔1s之后再运行一次。该线程的run方法判断当前路线集合里是否有车,有车的话再判断红绿灯状态是否允许通过,允许通过则把当前路线的车辆集合remove一次*/

Lamp类

S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
/* 解读: 控制路线的灯,因为方向只有12个,是一定的,所以使用了枚举类。构造的第一个参数表示与当前灯同时变绿(也就是通行情况一致)的对应路线,第二个参数表示当前灯变红时下一个变绿的灯, 第三个参数控制灯初始化时是否为绿*/


private Lamp(String opposite,String next,boolean lighted){
this.opposite = opposite;
this.next = next;
this.lighted = lighted;
}

private boolean lighted;
private String opposite;
private String next;
/* 解读: 灯状态参数 */

public boolean isLighted(){
return lighted;
}
/* 解读: 提供给Road线程,用以判断当前路线通行状态的方法 */

public void light(){
this.lighted = true;
if(opposite != null){
Lamp.valueOf(opposite).light();
}
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
}
/* 解读: 仅用于将某个灯变绿,并判断是否有可供点亮的反方向灯,如果有,它对应方向的灯也要变绿。注意这里使用了递归,也是为什么枚举的前两行明明互为opposite,但是第二行对象的opposite参数为null。 */

public Lamp blackOut(){
this.lighted = false;
if(opposite != null){
Lamp.valueOf(opposite).blackOut();
}

Lamp nextLamp= null;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.light();
}
return nextLamp;
}
/* 解读: 仅用于将某个灯变红,并判断是否有可供关闭的反方向灯,如果有,对应方向的灯也要变红。并且将下一个方向的灯变绿。因为next只是一个表明下一个灯对象名字的String对象,所以专门建立了nextLamp用于点亮下一个方向的灯 */

LampController类

private Lamp currentLamp;
/* 解读: 建立一个临时的灯对象 */

public LampController(){
currentLamp = Lamp.S2N;
currentLamp.light();
/* 解读: 系统初始时让由南向北的灯变绿; */

ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
System.out.println("来啊");
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
/* 解读: 每隔10秒将当前绿灯变为红灯,并让下一个方向的灯变绿,这里使用了和Road类一样的scheduleAtFixedRate定时器,线程建立后10s运行第一次,之后每隔10s运行一次,线程run方法功能为将当前灯状态改为禁止通行,并接收blackOut返回的nextLamp供下一次处理使用 */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值