交通燈管理系統
---------------------------------------------------------------------------------------------------------------------------------------------
項目名稱:
【【【交通燈管理系統】】】
模擬實現十字路口的交通燈管理系統邏輯,具體需求如下
1、異步隨機生成按照各個顯露行駛的車輛
1、異步隨機生成按照各個顯露行駛的車輛
例如:由南而來去往北的車輛--- 直行車輛由西而來去往南的車輛--- 右轉車輛由懂而來去往南的車輛--- 左轉這兩。。。
2、信號燈忽略 黃燈,只考慮紅燈和綠燈
3、應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制
4、具體信號燈控制邏輯與現實生活中的交通燈控制邏輯相同
3、應考慮左轉車輛控制信號燈,右轉車輛不受信號燈控制
4、具體信號燈控制邏輯與現實生活中的交通燈控制邏輯相同
不考慮特殊情況下的控制邏輯注:南北車輛與東南車輛交替放心,同方向等待車輛應放行直行車輛而後放行左轉車輛
5、每輛車通過路口時間爲1秒(提示:可通過線程sleep的方式模擬)
6、隨機生成車輛時間建個以及紅綠等叫特時間建個自定,可以設置
7、不要求實現GUI,只考慮系統邏輯實現,可通過LOG方式展現程序運行結果
----
個人感覺
1、找出關鍵對象2、實現單個對象相關功能3、改進相互間需要的部分功能4、進行測試、調節
----
配圖
配圖
分析:
1、 該項目涉及到:燈、車、路、控制器。
2、該十字路口,每個方向的車輛會有3種可能的行駛方向,得出合計有12條路線、同時也是12只燈
3、由此可見,設計到了:紅綠燈(題目不要求黃燈)、燈的變頻控制器、交通工具、路線。
4、如此:本項目設計到的(對象) 功能類:1、路線 2、紅綠燈、3、控制器 4測試類由於本項目只考慮系統邏輯實現,不要求實現交通工具運行移動的過程,只捕捉交通工具穿過路口的過程同時,交通工具運行到某一條路線上,需要觀察該路線上的紅綠燈,並且需要知道該自己在路線是否助於第一位置,才能決定是否通過。由此可見,交通工具在本項目中,只是充當路線上的一個元素,1、路線讓第一個通過馬路(依次),2、路線隨機生成後來的交通工具3、本項目有 12條路線
5、燈,邏輯上有12只紅綠燈,聯繫實際生活中,假設右轉的4只燈爲常綠
並且直線上的紅綠燈會兩兩對立(這組燈同時變綠燈--另外組則同時變紅燈)--與生活中一致了。如此一來,就只剩下4只燈(--對應4只燈--4只常綠燈)在這種設計思維下,編寫類的時候,應該初始化:1、對面的燈2、下一個燈3、燈的狀態
6、控制器,讓燈在規定的時間一到,就變色。應該用一個變頻定時器來完成
1、默認控制一個燈2、變頻定時器 定時變燈
7、測試類
1、創建 12條路線2、創建 控制器,開啓功能
---
思路
1、class Road 路線
思路
1、class Road 路線
1、路線應該初始化時就指定名稱2、路線隨機時間add 一輛車
構造函數不能直接創建線程--調用Thread.sleep();1、使用線程池,創建線程池對象2、創建線程
1、設定 隨機睡眠時間時間3、移除車輛--通過十字路口2、add 新車
1、需要用線程池對象2、創建一個定時器-按頻率移除
1、移除時要進行判斷--路線上是否有車1、判斷紅綠燈的狀態--綠燈才移除
2、enum Lamp 紅綠燈
1、創建時記得是 enum2、創建12只燈 分三組3、3個關鍵成員變量:
1、當前等的對面的燈2、當前燈的下一個燈3、當前燈的狀態
4、根據成員變量生成相關的方法
1、返回對面燈的方法2、返回下一個燈的方法3、返回當前燈狀態的方法4、表示等狀態的方法
1、亮狀態 >>對應- 綠
1、當前等亮的時候--對面的等同步變亮
2、黑狀態 >> 對應- 紅1、當前等黑的時候--對面的等同步變黑2、當前等變黑--同步下一組燈 變亮
5、由此得出 構造方法時,需要初始化3個關鍵元素。
3、class LampContorller 變頻控制器
1、默認控制一組燈2、構造方法初始化這隻燈爲 4組燈的某一個(不能是其他燈)3、構造方法初始化這隻燈狀態 爲 1、亮 2、黑4、繼續構建一個變頻定時器,進行燈的狀態的切換
1、其實很簡單,就是設定一個時間 時間-->變黑-->時間-->變亮 無限循環2、記住用Executors 線程池 的對象和方法來完成
4、class MainClass 啓動功能測試類
1、new 出12條線路2、new 控制器--> 開啓 交通燈測試3、可以把12只燈 放入一個數組--方便new 出12條線路
----------
具體代碼:
--
【】交通燈項目-1------Road 路線
【】交通燈項目-2----Lamp 紅綠燈
【】交通燈項目-3---------LampController 燈的控制器
【】交通燈項目-4 ------MainClass 測試類
----------
細節問題:
---
1、concurrent 包,對線程和線程池的使用
具體代碼:
--
【】交通燈項目-1------Road 路線
public class Road {
//R-1 首先是一個集合 表示每條路線上的車輛
private List<String> vehicles = new ArrayList<String>();
//R-2 每條路 應該有個名字
private String roadName = null;
//R-2-1 通過構造函數,使每創建一條路線的時候,就指定一個名字
public Road(String roadName){
this.roadName = roadName;
//r-3 不能在構造方法中直接Thread.sleep();所以new一個線程池
ExecutorService pool = Executors.newSingleThreadExecutor();
//r-3-1 execute執行 new Runnable 這個內部類
pool.execute(new Runnable(){
@Override//r-3-2 覆蓋 run方法
public void run() {
//r-3-2-1 假設每條路上最多999輛車
for(int i=1 ;i<1000 ;i++ ){
try {
//r-3-2-3 隨機生成一個1-10的數組*1000 就是秒 在這個時間裏後 完成添加
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//r-3-2-2 添加 交通工具 到集合
vehicles.add(Road.this.roadName + "_" + i);
//內部類訪問外部類:1 外部類用final 修飾變量 2、重名時候 用類名.this.變量名
}
}
});//command>> Runnable 線程
// pool.execute>>>end
//r-4 定時器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//r-4 定時器 執行一次,或者循環執行:
//timer.schedule(command, delay, unit) 只執行一次 下面這個是按頻率執行
//timer.scheduleAtFixedRate(command, initialDelay, period, unit)
//4個參數分別是;任務、循環頻率、多久執行一次、前2者的度量單位(秒、分、時等)
timer.scheduleAtFixedRate(
//r-4-1 4個參數分別是:1功能代碼、2、1 ,3、1、 4設定前2者爲秒
new Runnable(){
@Override// 功能代碼:
public void run() {
//r-4-2表示有車輛
if(vehicles.size()>0){
//r-4-3 假如 是綠燈
//boolean lighted = true;
//【】RL-1 Lamp.valueOf(name) 獲取到當前路線的燈 並 調用isLighted 判斷黑亮狀態
boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
if(lighted){
//r-4-4是綠燈就 讓第一輛車通行--就是移除 remove 會返回被移除的元素
System.out.println("this car:"+vehicles.remove(0)+"--- is traversing ---");;
}
}
}},
1,
1,
TimeUnit.SECONDS); // end
}
}
//【】RL-1 代表Road 完成並且 Lamp 完成 後
//Road end
【】交通燈項目-2----Lamp 紅綠燈
public enum Lamp {
// N
// W E
// S
//L-1 12個枚舉值
// S2N,S2W,E2W,E2S,//A 正面 - 主功能
// N2S,N2E,W2E,W2N,//b 對面
// S2E,W2S,N2W,E2N;//c 常綠燈
//[L-14]&&[L-12]&&[L-9]&& [L-1] 12個枚舉值
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),//A
//L-2 僅僅是建立枚舉值》》S2N
//L-9 僅僅是設定 對面燈》》S2N("N2S")
//L-12 設定燈的 [下一個燈]和 [默認黑亮狀態]、》》S2N("N2S","S2W",false)
//[L-14]把所有等都設置完畢--三個參數,右拐常綠
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),//b
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);//c
//L-10 構造方法 獲取對面的燈
//L-12 給構造方法添加 下一個燈、默認黑亮參數
//Lamp(String oppsite){ //傳遞Lamp oppsite 要報錯 通過傳遞String 表示名字來解決
private Lamp(String oppsite,String next,boolean lighted){ //參數:對應燈、下一個燈、默認黑亮狀態
this.oppsite = oppsite;
this.next = next;
this.lighted = lighted;
}// L-10、L-12 end
//L-2 交通燈就應該有一個[燈的狀態]----表示是亮黑是黑(亮綠,黑紅)
private boolean lighted;
//L-6 A [對面的燈] 的名字
private String oppsite;
//L-13 定義[下一個燈]的名字
private String next;
//L-8 判斷這個燈的狀態 ,是亮黑是黑?
public boolean isLighted(){
return lighted;
}
//L-3 知道是黑是亮後 對面的燈需要同步變化、:
//L-4 亮狀態
public void light(){
// this.lighted=true;
//L-7 的A中的燈亮,則對面的燈同步變亮
oppsite.light();
//這裏很容易形成死循環,應該通過構造方法設計爲,A對應B, B沒有對應的,不形成循環。
this.lighted = true;
if(oppsite != null){ //A有對應的燈 才亮, 着時候B 沒有對應的,就不會亮
//L-11 構造方法獲取到名字以後給枚舉,枚舉就能返回枚舉值對象,再調用亮燈
Lamp.valueOf(oppsite).light();
//oppsite.light();
}
System.out.println("this Lamp "+name() +"------>> to Green 共有6發方向可以通行" );
}
//L-5 黑 狀態
public Lamp blackOut(){
this.lighted=false;
//L-15 同//L-7 正面的燈變黑,對面的也變黑。
if(oppsite != null){
Lamp.valueOf(oppsite).blackOut();
}
//L-16 這個燈變黑,則下一個燈 則 變亮--變綠
// if(next != null){
// Lamp.valueOf(next).light();//Lamp end
// }
//LC-1 控制器改進代碼
Lamp nextLamp = null ;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("【this Green Lamp :"+name() +"------>> to : " +next+"】");
nextLamp.light();//Lamp end
}
//LC-2 讓該方法 在同步變黑的時候,返回下一個燈
return nextLamp;
}
}
//Lamp end
【】交通燈項目-3---------LampController 燈的控制器
public class LampController {
//1、 燈的控制器,肯定要控制一個燈
private Lamp currentLamp;
public LampController(){
//2、初始化當前燈線路、狀態
currentLamp = Lamp.S2N;
currentLamp.light();
//3、燈是按照規律來變化的,所以要設計一個 頻率定時器
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
//3-1 4參數 設定頻率爲10秒,Run功能10運行一次
timer.scheduleAtFixedRate(
new Runnable(){
public void run(){
//3-2 應該設計這個燈變黑後,下個等變綠,並且再次調用的時候,是把綠變黑。
//3-3修改 Lamp 類L-16 爲:LC-2 currentLamp 具有記憶功能
// blackOut 變黑,並返回下一個燈 所以currentLamp 是下一個的, 這樣就循環起來了。
System.out.println("10秒一次來了");
currentLamp = currentLamp.blackOut();
}
},
10,
10,
TimeUnit.SECONDS);
}
}
//LampController end
【】交通燈項目-4 ------MainClass 測試類
public class MainClass {
public static void main(String[] args) {
//1、new 出12 條路線
//2、new出控制器
//1-1
String [] directions = new String[]{
"S2N","S2W","E2W","E2S","N2S","N2E","W2E","W2N","S2E","E2N","N2W","W2S"
};
for(int i=0;i<directions.length;i++){
new Road(directions[i]);
//new Test_R(directions[i]);
}
//模擬交通燈 runing:
new LampController();
}
}//MainClass end
----------
細節問題:
---
1、concurrent 包,對線程和線程池的使用
Executor: 併發 執行已提交的 Runnable 任務的對象 的接口以前沒學過,目前瞭解來說構造方法中不能直接創建線程,通過concurrent 裏的對象能夠達到相同目的
Executors: 多線程
static ExecutorService newSingleThreadExecutor():
static ExecutorService newFixedThreadPool(int nThreads) :創建單個線程
static ScheduledExecutorService newScheduledThreadPool():創建線程池
ScheduledExecutorService:可安排在給定的延遲後運行或定期執行的命令 的接口創建一個線程池,它可安排在給定延遲後運行命令或者定期地執行。
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) :
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)創建並執行在給定延遲後啓用的一次性操作。
創建並執行一個在給定初始延遲後首次啓用的定期操作,後續操作具有給定的週期;
TimeUnit unit :是代表long delay或者long initialDelay 的時間單位的 是一個枚舉 值是:天、時、分、秒等
2、本項目中細節代碼
1、
ExecutorService pool = Executors.newSingleThreadExecutor();
pool.execute(new Runnable(){
public void run() {
for(int i=1 ;i<1000 ;i++ ){
try {
Thread.sleep((new Random().nextInt(10)+1)*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
vehicles.add(Road.this.roadName + "_" + i);
}
}
});
1、拿到線程池的對象2、調用execute 來創建線程3、execute方法的參數 採用內部類完成
1、線程 Runnable必須覆蓋 run 方法
1、Thread.sleep((new Random().nextInt(10)+1)*1000); 生成隨機睡眠時間2、vehicles.add(Road.this.roadName+ "_" + i); 添加了一個新的交通工具
2、
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable(){
public void run() {
if(vehicles.size()>0){
//boolean lighted = true;
boolean lighted = Lamp.valueOf(Road.this.roadName).isLighted();
if(lighted){
System.out.println("this car:"+vehicles.remove(0)+"--- is traversing ---");;
}
}
}},
1,
1,
TimeUnit.SECONDS); // end
1、拿到定時器對象2、通過對象 的scheduleAtFixedRate 方法實現 頻率定時器3、參數爲 線程、頻率時、功能運行時、前2者世間單位1、線程 Runnable必須覆蓋 run 方法1、判斷當前路線的交通工具是否有車1、判斷當前等的狀態-是黑還是亮1、移除集合第一個元素--達到第一輛車通過十字路口。
3、
public void light(){
this.lighted = true;
if(oppsite != null){
Lamp.valueOf(oppsite).light();
}
System.out.println("this Lamp "+name() +"------>> to Green 共有6發方向可以通行" );
}
1、設定 狀態 lighted 爲 true 表示亮2、有對面關係,則讓對面同亮--枚舉設定只有單對面(A>>>>b , b>>>> null)
4、
public Lamp blackOut(){
this.lighted=false;
if(oppsite != null){
Lamp.valueOf(oppsite).blackOut();
}
Lamp nextLamp = null ;
if(next != null){
nextLamp = Lamp.valueOf(next);
System.out.println("【this Green Lamp :"+name() +"------>> to : " +next+"】");
nextLamp.light();//Lamp end
}
return nextLamp;
}
1、當前燈爲黑--對面等同步爲黑2、當前燈爲黑--下一組燈同步爲亮3、把下一組等提取到判斷外
5、
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);
1、12組燈 分三組
1組:主實現功能
1、包含3個參數
1、下一組燈2、對面的燈3、等的狀態
2組:1組對面燈3組:常綠燈
6
對應5
1、構造函數進行初始化狀態
2、初始化 參數:對面燈、下一個燈、黑亮狀態
3、其他需要注意的方法
private Lamp(String oppsite,String next,boolean lighted){
this.oppsite = oppsite;
this.next = next;
this.lighted = lighted;
}
1、構造函數進行初始化狀態
2、初始化 參數:對面燈、下一個燈、黑亮狀態
3、其他需要注意的方法
Thread.sleep(1000): 線程方法睡眠1000毫秒(new Random().nextInt(10)+1): 隨機生成1-10的數字
4、用到的生詞
Road: 路
Lamp: 燈
isoftstone: 軟通動力 官網
Interview: 面試
traffic: 燈
Vehicles: 交通
execute 執行
lighted 點亮、亮
oppsite 對應的
controller 控制器
current 當前的
direction 方向
light
blackOut
Lamp: 燈
isoftstone: 軟通動力 官網
Interview: 面試
traffic: 燈
Vehicles: 交通
execute 執行
lighted 點亮、亮
oppsite 對應的
controller 控制器
current 當前的
direction 方向
light
blackOut
-------
運行結果:
設定的第一個燈是S2N
運行到這裏, 已經是一個輪迴了。
無限循環執行。
上述代碼和上述圖片結果有輕微不同。 不影響功能的演示。
---------------------------------------------------------------------------------------------------------------------------------------------
---------- android培訓、 java培訓 、期待與您交流!----------
----------------------------------------------