黑马程序员-----------------交通灯管理系统


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

交通灯管理系统

· Concurrent [kən'kʌr(ə)nt]adj. 并发的;一致的;同时发生的

· Executors[ɪg'zɛkjətɚ]n. 执行者;[法] 遗嘱执行人;执行器

· scheduled['ʃedjuːld]adj. 预定的;调度

· service ['sɜːvɪs]n. 服务,服侍;服役;仪式

· pool [puːl]池

fixedrate固定频率  

vechicles交通工具 

directions [dɪ'rekʃ(ə)nz]n. 方向

Traversing n. 穿越,通过

opposite ['ɒpəzɪt; -sɪt] 对面

  

  2.必须理解类和接口与方法

java.util.concurrent Executor接口:执行已提交的 Runnable 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。通常使用 Executor 而不是显式地创建线程。

void

execute(Runnable command) 
          在未来某个时间执行给定的命令。

 

java.util.concurrent ScheduledExecutorService接口:

      ScheduledFuture<?>

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 
          创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。

 

java.util.concurrent Executors类:此包中所定义的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory 和 Callable 类的工厂和实用方法。

static ScheduledExecutorService

newScheduledThreadPool(int corePoolSize) 
          创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。

 

一、题目要求

        模拟实现十字路口的交通灯管理系统逻辑,具体需求如:

1、异步随机生成按照各个路线行驶的车辆。

例如:

        由南向而来去往北向的车辆 ----直行车辆

        由西向而来去往南向的车辆 ----右转车辆

        由东向而来去往南向的车辆 ----左转车辆

        。。。

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

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

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

5、注:

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

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

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

        4)不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

二.题目图解:

 

 

1.对图形和题目分析

1) 汽车行驶路线共12条,每条路线作为一个对象存在。为了统一模型,

2) 假设每条路线有红绿灯存在。其中右转弯的4条路线的控制灯可以假设称为常绿状态。

3) 另外,其他的8条线路是两两成对的,可以归为4组。(原因:两个相对的灯一个变红,其相对的就要变绿)

4)所以,程序只需考虑图中标注了数字的4条路线的控制灯的切换顺序,这4条路线相反方向的路线的控制灯跟随这4条路线切换,不必额外考虑。

2.面向对象的分析。

面向对象有:红绿灯,红绿灯的控制系统,汽车,路线。

面向对象的经验:谁拥有数据,谁就对外提供操作这些数据的方法。

注意问题:

1)因为只有12个灯所以可以用枚举。

2)汽车与路线是绑定的。

3)汽车过红绿灯时不但要与交通灯有关系,还与汽车相互之间有关系。(原因是我们过红绿灯的时候不单只是看灯,还要看车。)

4)程序中如何知道自己前面是否有车,这时候则访问路线对象。(路就要有增加车辆和减少车辆的方法)

3.面向对象的设计。

路的设计:

1)因为有路才有车所以汽车与路线是绑定的,这样汽车可以当做是路的内部类。

2)因为每个车也是一个对象,所以创建一个集合来存储汽车对象。

3)制作定时器,每隔一秒检查对应的灯是否为绿,是则放行一辆车 

4)汽车的通过路口则用,删除集合元素来来表示。

红绿灯的设计:

1)假设有12个灯所以就有12个对象,因为对象可以计算的出来所以用枚举表示。

2)不存在逻辑的灯:

车向右拐的四个交通灯:都是常绿的。(S2EE2NN2WW2S

3)存在逻辑的只有四组灯。

车直走的四个交通灯:一边灯变绿的时候,其相对的另一边也变绿,其为一组共两组。(S2NN2SE2WW2E

车左拐的四个交通灯:也是相对的,一边变绿,另外一边也变绿,所以也是两组。(S2WN2EE2SW2N)

4)灯有三个变量:

一个是自己的状态。

一个是其相对方的灯。

一个是其下一个方向的灯。

5)灯的设计技巧:

一个灯变绿,那么其返回的值则表示下一个灯变红。

红绿灯控制系统设计:

1)初始化第一个交通灯

2)通过定时器,设定每隔10秒交通灯变一次颜色。

三.程序编写

1.Road类的编写

1)创建一个可以存储汽车的集合。

2)创建一个线程来创建汽车对象。

3)创建一个定时器,来检查汽车锁对应的等是否变绿。

package jiaotongdeng;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
//这个是车开到路上来的代码。
 
 
public class Road {
//创建一个车的集合。
List<String> vechicles = new ArrayList<String>();
 
//每条路要有名字,这样才好为车起名字。
private String name = null;
public Road(String name){
this.name = name;
//模拟车辆不断随机上路的过程,使用线程池,通过产生单个线程的方法,创建一个线程池 .
ExecutorService pool =  Executors.newSingleThreadExecutor();//Executors为线程池中单线程
pool.execute(new Runnable() {
public void run() {
//用构造方法产生999量车
for(int i =1; i < 1000; i++){
try {
Thread.sleep((new Random().nextInt(10) + 1) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//车辆进入路线中
//内部类访问外部成员Road.this
vechicles.add(Road.this.name + "_" + i);
}
}
});
//制作定时器,每隔一秒检查对应的灯是否为绿,是则放行一辆车 
ScheduledExecutorService timer= Executors.newScheduledThreadPool(1);//线程池中的调度池
timer.scheduleAtFixedRate(
new Runnable(){//指要干的事情
public void run(){
//把集合里面的第一辆车给移走
if(vechicles.size()>0){//检查集合内部有没有车,有车则得到路线上的灯。
boolean lighted = lamp.valueOf(Road.this.name).isLighted();
if(lighted){//当灯是绿的。lighted表示绿灯。
System.out.println(vechicles.remove(0) + " is traversing!");
}
}
}
}, 
1, //指过多少秒去干这个事
1, //再过多少秒接着干
TimeUnit.SECONDS);//时间的度量单位
}
}


2.Lamp类的编写

1)因为只有12个交通灯,所以直接用枚举来创建对象更方便。

2)为灯的枚举设置属性,分别指目前的灯的对面的灯,下一个灯,等是否是绿色。

3)创建三个变量,一个是自己的状态,一个表示相对的灯,一个表示下一个灯。

4)创建检查灯是否变绿的方法。

5)创建让其对应的灯同时变绿的方法。

6)创建把等变红的方法,并且返回下一个灯。

package jiaotongdeng;
 
public enum lamp {
//S代表南,N代表北,W代表西,E代表东。
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("S2E","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);
//枚举的构造方法一定是私有的
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;
}
 
public void light(){//先让灯变绿再让其对应的灯变绿。
this.lighted = true;//表示
if(opposite != null){//这表示有对应的灯亮才亮。
lamp.valueOf(opposite).light();
}
System.out.println(name() + "lamp is Green,下面总共应该有6个方向能看到汽车穿过!");
}
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;
}
}


3.LampControlle类的编写

1)初始化交通灯。

2)设置定时器让灯每隔10秒变一次颜色。

package jiaotongdeng;
 
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
public class lampController {
//初始化交通灯
private lamp currentLamp;//当前的灯。
public lampController(){
currentLamp = lamp.S2N;//首先指定第一个灯。
currentLamp.light();//指定第一个灯为绿
//定时器,没隔10秒钟让这个灯变黑下一个等变绿。
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run() {
System.out.println("来了");
//每隔10秒钟把当前的灯变黑
currentLamp = currentLamp.blackOut();
}
},
10, 
10, 
TimeUnit.SECONDS);
}
 
}


4.mainClass主函数的编写

1)创建存储路方向的数组。

2)创建路方位的对象。

3)创建交通控制系统。

package jiaotongdeng;
 
public class MainClass {
 
/**
 * @param args
 */
public static void main(String[] args) {
//创建存储方位的数组。
String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2S"
};
//创建路方位的对象。
for(int i = 0; i < directions.length; i++){
new Road(directions[i]);
}
//创建交通控制系统
new lampController();
}
 
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值