熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

交通燈管理系統

2013-11-23 19:24:06  來源: Java核心技術 
    模擬實現十字路口的交通燈管理系統邏輯具體需求如下
   
    異步隨機生成按照各個路線行駛的車輛
   
例如
   
    由南向而來去往北向的車輛 直行車輛
   
    由西向而來去往南向的車輛 右轉車輛
   
    由東向而來去往南向的車輛 左轉車輛
   
    …
   
    信號燈忽略黃燈只考慮紅燈和綠燈
   
    應考慮左轉車輛控制信號燈右轉車輛不受信號燈控制
   
    具體信號燈控制邏輯與現實生活中普通交通燈控制邏輯相同不考慮特殊情況下的控制邏輯
   
    注南北向車輛與東西向車輛交替放行同方向等待車輛應先放行直行車輛而後放行左轉車輛
   
    每輛車通過路口時間為秒(提示可通過線程Sleep的方式模擬)
   
    隨機生成車輛時間間隔以及紅綠燈交換時間間隔自定可以設置
   
    不要求實現GUI只考慮系統邏輯實現可通過Log方式展現程序運行結果
   
    在這裡面需要弄三個類Road;Lamp;LampController;mainClass
   
    Road
   
    每個Road對象都有一個name成員變量來代表方向有一個vehicles成員變量來代表方向上的車輛集合
   
    在Road對象的構造方法中啟動一個線程每隔一個隨機的時間向vehicles集合中增加一輛車(用一個路線名_id形式的字符串進行表示)
   
    在Road對象的構造方法中啟動一個定時器每隔一秒檢查該方向上的燈是否為綠是則打印車輛集合和將集合中的第一輛車移除掉
   
    package comtaobaointerview;
   
    import javautilArrayList;
   
    import javautilList;
   
    import javautilRandom;
   
    import ncurrentExecutorService;
   
    import ncurrentExecutors;
   
    import ncurrentScheduledExecutorService;
   
    import ncurrentTimeUnit;
   
    public class Road {
   
    private String name;
   
    private List<String> vechicles = new ArrayList<String>()
   
    public Road(String name){
   
    thisname = name;
   
    ExecutorService pool = ExecutorsnewSingleThreadExecutor()
   
    poolexecute(new Runnable() {
   
    @Override
   
    public void run() {
   
    for(int i=;i<;i++){
   
    try {
   
    Threadsleep(new Random()nextInt()*
   
    vechiclesadd(Roadthisname+i)
   
    } catch (InterruptedException e) {
   
    // TODO Autogenerated catch block
   
    eprintStackTrace()
   
    }
   
    }
   
    }
   
    })
   
    ScheduledExecutorService timer = ExecutorsnewScheduledThreadPool(
   
    timerscheduleAtFixedRate(new Runnable() {
   
    @Override
   
    public void run() {
   
    if(vechiclessize()> && LampvalueOf(Roadthisname)isLighted())
   
    Systemoutprintln(vechiclesremove()+有車行駛
   
    }
   
    }
   
   
   
   
   
    TimeUnitSECONDS)
   
    }
   
    }
   
    Lamp
   


    系統中有個方向上的燈在程序的其他地方要根據燈的名稱就可以獲得對應的燈的實例對象綜合這些因素將Lamp類用java中的枚舉形式定義更為簡單
   
    每個Lamp對象中的亮黑狀態用lighted變量表示選用SNSWEWEN這四個方向上的Lamp對象依次輪詢變亮Lamp對象中還要有一個oppositeLampName變量來表示它們相反方向的燈再用一個nextLampName變量來表示此燈變亮後的下一個變亮的燈這三個變量用構造方法的形式進行賦值因為枚舉元素必須在定義之後引用所以無法再構造方法中彼此相互引用所以相反方向和下一個方向的燈用字符串形式表示
   
    增加讓Lamp變亮和變黑的方法light和blackOut對於SNSWEWEN這四個方向上的Lamp對象這兩個方法內部要讓相反方向的燈隨之變亮和變黑blackOut方法還要讓下一個燈變亮
   
    除了SNSWEWEN這四個方向上的Lamp對象之外其他方向上的Lamp對象的nextLampName和oppositeLampName屬性設置為null即可並且SNSWEWEN這四個方向上的Lamp對象的nextLampName和oppositeLampName屬性必須設置為null以便防止light和blackOut進入死循環
   
    package comtaobaointerview;
   
    public enum Lamp {
   
    SN(NSfalseSWSW(NEfalseEWEW(WEfalseESES(WNfalseSN
   
    NS(nullfalsenull)NE(nullfalsenull)WE(nullfalsenull)WN(nullfalsenull)
   
    WS(nulltruenull)SE(nulltruenull)EN(nulltruenull)NW(nulltruenull)
   
    private String opposite;
   
    private String next;
   
    private boolean lighted;
   
    private Lamp(String oppostieboolean lightedString next){
   
    thisopposite = oppostie;
   
    thislighted = lighted;
   
    thisnext = next;
   
    }
   
    public void light(){
   
    lighted = true;
   
    if(opposite!=null){
   
    Lamp oppLamp = LampvalueOf(opposite)
   
    oppLamplight()
   
    }
   
    Systemoutprintln(thisname()+方向綠燈亮了可以行駛
   
    }
   
    public Lamp black(){
   
    lighted = false;
   
    Lamp nextLamp = null;
   
    if(opposite!=null){
   
    LampvalueOf(opposite)black()
   
    }
   
    if(next!=null){
   
    Systemoutprintln(next)
   
    nextLamp = LampvalueOf(next)
   
    nextLamplight()
   
    }
   
    return nextLamp;
   
    }
   
    public boolean isLighted(){
   
    return lighted;
   
    }
   
    }
   
    LampController
   
    整個系統中只能有一套交通燈控制系統所以LampController類最好是設計成單例
   
    LampController構造方法中要設定第一個為綠的燈
   


    LampController對象的start方法中將當前燈變綠然後啟動一個定時器每隔秒將當前燈變紅和將下一個燈變綠
   
    package comtaobaointerview;
   
    import ncurrentExecutor;
   
    import ncurrentExecutors;
   
    import ncurrentScheduledExecutorService;
   
    import ncurrentTimeUnit;
   
    public class LampController {
   
    private Lamp currentLamp;
   
    public LampController(){
   
    currentLamp = LampSN;
   
    currentLamplight()
   
    ScheduledExecutorService timer =  ExecutorsnewScheduledThreadPool(
   
    timerscheduleAtFixedRate(new Runnable(){
   
    public void run(){
   
    currentLamp = currentLampblack()
   
    }
   
    }
   
   
   
   
   
    TimeUnitSECONDS)
   
    }
   
    }

    總結
   
    每條路線上都會出現多輛車路線上要隨機增加新的車在燈綠期間還要每秒鐘減少一輛車
   
    設計一個Road類來表示路線每個Road對象代表一條路線總共有條路線即系統中總共要產生個Road實例對象
   
    每條路線上隨機增加新的車輛增加到一個集合中保存
   
    每條路線每隔一秒都會檢查控制本路線的燈是否為綠是則將本路線保存車的集合中的第一輛車移除即表示車穿過了路口
   
    每條路線每隔一秒都會檢查控制本路線的燈是否為綠一個燈由綠變紅時應該將下一個方向的燈變綠
   
    設計一個Lamp類來表示一個交通燈每個交通燈都維護一個狀態亮(綠)或不亮(紅)每個交通燈要有變亮和變黑的方法並且能返回自己的亮黑狀態
   
    總共有條路線所以系統中總共要產生個交通燈右拐彎的路線本來不受燈的控制但是為了讓程序采用統一的處理方式故假設出有四個右拐彎的燈只是這些燈為常亮狀態即永遠不變黑
   
    除了右拐彎方向的其他條路線的燈它們是兩兩成對的可以歸為所以在編程處理時只要從這組中各取出一個燈對這個燈依次輪詢變亮與這個燈方向對應的燈則隨之一同變化因此Lamp類中要有一個變量來記住自己相反方向的燈在一個Lamp對象的變亮和變黑方法中將對應方向的燈也變亮和變黑每個燈變黑時都伴隨者下一個燈的變亮Lamp類中還用一個變量來記住自己的下一個燈
   
    無論在程序的什麼地方去獲得某個方向的燈時每次獲得的都是同一個實例對象所以Lamp類改用枚舉來做顯然具有很大的方便性永遠都只有代表個方向的燈的實例對象
   
    設計一個LampController類它定時讓當前的綠燈變紅
   
    這是一個很好的題收獲很多


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26806.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.