最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java多線程模擬交通燈管理系統(tǒng)

 更新時間:2021年08月15日 16:44:08   作者:Lukegwo  
這篇文章主要為大家詳細介紹了java多線程模擬交通燈管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了java多線程模擬交通燈管理系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下

一、項目業(yè)務(wù)邏輯分析

項目需求:模擬實現(xiàn)十字路口的交通燈管理系統(tǒng)邏輯,要求如下:

  • 異步隨機生成按照各個路線行駛的車輛,例如由北向南行駛的車輛、由東向南行駛的車輛。
  • 信號燈忽略黃燈,只考慮紅燈和綠燈的情況。
  • 左轉(zhuǎn)受信號燈控制,右轉(zhuǎn)車輛不受信號燈控制,其他情況與現(xiàn)實生活的邏輯相同。
  • 注:南北向車輛和東西向方向車輛交替放行,同方向等待車輛應(yīng)先放行直行車輛,而后再放行左轉(zhuǎn)車輛。
  • 每輛車通過路口所需時間為1秒(提示:可以通過線程的sleep方法模擬)。
  • 隨機生成車輛,時間間隔以及紅綠燈交換時間自定。
  • 不要求GUI,只考慮系統(tǒng)邏輯實現(xiàn)??稍谠诮K端log方式模擬。

首先了解一下現(xiàn)實中十字路口的交通燈的業(yè)務(wù)邏輯(為此我大晚上在十字路口仔細觀察了半個小時,缺少生活啊。),直接上圖吧,直觀明了:

額,乍一看有點亂,仔細一想很簡單,就是東西南北四條路每條路都有三個去向,左轉(zhuǎn)、右轉(zhuǎn)和直行,這樣一個十字路口就有了12個行駛方向。每個方向都有一個指示燈,也就是12個信號燈,如果每個信號燈都單獨控制,那就麻煩多了,而且很不科學(xué),得一天24小時堵車。需求第3點說明右轉(zhuǎn)不受信號燈控制,其實現(xiàn)實生活照也是這樣,一般右轉(zhuǎn)車輛不受控制的(比較繁忙的路口受控制),隨時可以轉(zhuǎn),也就是說永遠是綠色等,想不通為什么這樣設(shè)計?而 對立面的燈是同步變化的,同時綠或者同時紅,這樣只需要系統(tǒng)控制一個方向的燈就可以了。最后我們只需要控制四個方向的燈就行了,這里選擇了圖中標記的①②④③四條路線,只要在改變其中一條路線的信號燈時同步改變對立面的燈為相同信號就行了。另外還要同時把下一個信號燈切換成相反的信號,例如S2W變紅時,同時N2E也要變紅,并且E2W或W2E變綠。這里我們選擇逆時針方向輪循。

二、系統(tǒng)詳細設(shè)計

根據(jù)業(yè)務(wù)需求分析,需要對象:信號燈、信號燈控制系統(tǒng)、汽車和路線。下面具體分析每個對象所以屬性和方法。
信號燈類(Lamp):信號燈只有紅和綠兩種狀態(tài),用boolean變量表示,true表示綠燈,false表示紅燈。還要提供切換信號燈狀態(tài)的方法turnRed和turnGreen。
信號燈控制系統(tǒng)(LampController):控制系統(tǒng)主要負責(zé)在規(guī)定時間切換紅綠燈,并隨著此類的創(chuàng)建,整個系統(tǒng)就開始運作,所以把系統(tǒng)啟動的實現(xiàn)放在了構(gòu)造方法內(nèi)。
汽車(Vihicles):這里只需要體現(xiàn)汽車穿過路口的過程不需要體現(xiàn)移動細節(jié),也就是捕捉路上減少一輛車的過程,所以,這個車并不需要單獨設(shè)計成為一個對象,用一個字符串表示就可以了。并且車是屬于公路的,應(yīng)該是一種聚合關(guān)系,根據(jù)擁有數(shù)據(jù)者應(yīng)提供訪問數(shù)據(jù)的方法的規(guī)律,這里路要提供增減車輛的方法。
路線(Road):每輛汽車不是看到對面的信號燈變綠就可以穿過的,要按照路線上的車隊順序依次通過路口,這個深有體會,堵車有時兩次綠燈都過不去路口。

根據(jù)以上分析類圖設(shè)計如下:

類圖很簡單,可以看出這三個類之間只是簡單的關(guān)聯(lián), Road中要用到Lamp的信號燈狀態(tài)判斷是否放行車輛,LampController負責(zé)定時切換Lamp的信號燈狀態(tài)。具體實現(xiàn)時為了方便有些方法的功能是放在構(gòu)造方法里實現(xiàn)的。

三、具體實現(xiàn)

Lamp類:

public enum Lamp {
 /**
  * E2W=East to West, N2S=North to South
  * 從南面的交通燈開始,逆時針執(zhí)行
  */
 //初始狀態(tài)為紅燈
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),
 E2W("W2E","E2S",false),E2S("W2N","S2N",false),
 //對立面紅燈
 N2E(null,null,false),N2S(null,null,false),
 W2E(null,null,false),W2N(null,null,false),
 //四個右轉(zhuǎn)方向,始終時綠燈
 S2E(null,null,true),E2N(null,null,true),
 N2W(null,null,true),W2S(null,null,true);
 
 //燈的狀態(tài) true=green,false=red
 private boolean lighted;
 private String opposite=null;
 private String next=null;
 
 private Lamp() {}
 /**
  * @param opposite 對面的燈
  * @param nexe   下一個燈 
  * @param initLighted 燈的初始狀態(tài)
  */
 private Lamp(String opposite,String next,boolean initLighted){
  this.opposite=opposite;
  this.next=next;
  this.lighted=initLighted;
  
 }
 //判斷燈的狀態(tài)
 public boolean getLighted(){
  return lighted;
 }
 //綠燈亮  同時把對面的燈設(shè)為綠  下一個燈設(shè)為紅燈
 public void turnGreen(){
  this.lighted=true;
 
  //如果對面有燈 
  if(opposite!=null){
   Lamp.valueOf(opposite).turnGreen();
  }
 }
 //紅燈亮  對立面的燈也變紅
 public Lamp turnRed(){
  this.lighted=false;
  Lamp nextGreenLamp=null;
  //對面的燈 同步變化
  if(opposite!=null){
   Lamp.valueOf(opposite).turnRed();
  }
  //下一個燈 綠燈亮 
  if(next!=null){
   nextGreenLamp=Lamp.valueOf(next);
   nextGreenLamp.turnRed();
  }
  return nextGreenLamp;
 }
}

Road類:

public class Road {
 //存放每條路上的車輛   車名就表示一輛車 
 private List<String> vehicles=new ArrayList<String>();
 private  String roadName=null;
 public Road(String roadName) {
  super();
  //根據(jù)路的方向取名,名字和對面的紅綠燈同名 E2W表示東向西的路
  this.roadName = roadName;
  
  //用線程池啟動一個線程,隨機產(chǎn)生一輛車
  Executors.newSingleThreadExecutor().execute(new Runnable(){
   @Override
   public void run() {
    for(int i=1;i<1000;i++){
     try {
      //每隔1~10秒 隨機產(chǎn)生一輛車
      Thread.sleep((new Random().nextInt(10)+1)*1000);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     //訪問外部類的成員變量
     vehicles.add(Road.this.roadName+"路 第  "+i+" 輛車");
    }
   }
   
  });
  /*
   * 定義一個計時器 使這條路每隔1s 就檢查一次這條路對應(yīng)的交通燈的狀態(tài)
   * 如果是綠燈 就每隔1s使離一輛車
   */
  ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(new Runnable(){
 
   @Override
   public void run() {
    //先判斷這條路上是否有車
    if(vehicles.size()>0){
     //在判斷交通燈狀態(tài)   
     boolean lighted=Lamp.valueOf(Road.this.roadName).getLighted();
     if(lighted){
      //從汽車列表中移除  并提示已通過路口
      System.out.println(vehicles.remove(0)+"通過路口。。。");
     }
    }
   }
   
  }, 1, 1, TimeUnit.SECONDS);
 }
}

LampController類:

//燈控系統(tǒng)
public class LampController {
 private Lamp currentLamp;
 
 public  LampController() {
  super();
  //交通燈系統(tǒng)初始化   第一個運行的S2N turn green
  this.currentLamp = Lamp.S2N;
  this.currentLamp.turnGreen();
  //定時器 每個10s 切換一次信號燈狀態(tài)
  ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
  timer.scheduleAtFixedRate(new Runnable(){
 
   @Override
   public void run() {
     currentLamp=currentLamp.turnRed();
   }
   
  }, 10, 10, TimeUnit.SECONDS);
  
 }
}

運行結(jié)果:

四、總結(jié)

本題目整體結(jié)構(gòu)很簡單,不涉及復(fù)雜的設(shè)計模式,重點是對業(yè)務(wù)邏輯的分析,首先要搞明白交通信號燈的運行機制,如果不考慮右轉(zhuǎn)的情況,簡答理解就是東西方向和南北方向的車輛交替放行,同方向等待紅燈的車輛先放行直行車輛一段時間,然后再放行左轉(zhuǎn)的車輛。在具體實現(xiàn)上有兩個難點:其一就是利用線程設(shè)置定時器,實時監(jiān)控每條路上的信號燈狀態(tài)和模擬隨機在各個方向的路上產(chǎn)生一些車輛,控制系統(tǒng)的任務(wù)比較簡單只需要定時輪流切換信號燈狀態(tài)。其二是巧妙的把四個方向的信號燈設(shè)計成了一個環(huán)形鏈表,控制系統(tǒng)只需要控制一個信號燈,其他3個就有規(guī)律的聯(lián)動運行了。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot獲取http數(shù)據(jù)、打印HTTP參數(shù)的4種方式

    SpringBoot獲取http數(shù)據(jù)、打印HTTP參數(shù)的4種方式

    Java的話本地打斷點可以調(diào)試獲取rest入?yún)?但是在生產(chǎn)環(huán)境可能我們獲取入?yún)ⅲ℉ttp?header/parameter)可能就沒有那么的輕松了,所以本文給大家介紹了SpringBoot獲取http數(shù)據(jù)、打印HTTP參數(shù)的4種方式,需要的朋友可以參考下
    2024-03-03
  • Java數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之順序表的實現(xiàn)

    線性表(linear?list)是n個具有相同特性的數(shù)據(jù)元素的有限序列。?線性表是一種在實際中廣泛使用的數(shù)據(jù)結(jié)構(gòu),本文將用Java實現(xiàn)順序表,感興趣的可以了解一下
    2022-09-09
  • 詳解springMVC—三種控制器controller

    詳解springMVC—三種控制器controller

    本篇文章主要介紹了springMVC—三種控制器controller,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 解決Idea報錯There is not enough memory to perform the requested operation問題

    解決Idea報錯There is not enough memory 

    在使用Idea開發(fā)過程中,可能會遇到因內(nèi)存不足導(dǎo)致的閃退問題,出現(xiàn)"There is not enough memory to perform the requested operation"錯誤時,可以通過調(diào)整Idea的虛擬機選項來解決,方法是在Idea的Help菜單中選擇Edit Custom VM Options
    2024-11-11
  • Java Swing組件實現(xiàn)進度監(jiān)視功能示例

    Java Swing組件實現(xiàn)進度監(jiān)視功能示例

    這篇文章主要介紹了Java Swing組件實現(xiàn)進度監(jiān)視功能,結(jié)合完整實例形式詳細分析了Java基于Swing組件實現(xiàn)進度條顯示功能的具體操作技巧與相關(guān)注意事項,需要的朋友可以參考下
    2018-02-02
  • Java?BOI與NIO超詳細實例精講

    Java?BOI與NIO超詳細實例精講

    在Java的軟件設(shè)計開發(fā)中,通信架構(gòu)是不可避免的,我們在進行不同系統(tǒng)或者不同進程之間的數(shù)據(jù)交互,或者在高并發(fā)下的通信場景下都需要用到網(wǎng)絡(luò)通信相關(guān)的技術(shù),對于一些經(jīng)驗豐富的程序員來說,Java早期的網(wǎng)絡(luò)通信架構(gòu)存在一些缺陷,這篇文章介紹Java?BOI與NIO
    2022-11-11
  • 基于Java的界面開發(fā)詳細步驟(用戶注冊登錄)

    基于Java的界面開發(fā)詳細步驟(用戶注冊登錄)

    通過一段時間Java Web的學(xué)習(xí),寫一個簡單的注冊登陸界面來做個總結(jié),這篇文章主要給大家介紹了基于Java的界面開發(fā)(用戶注冊登錄)的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-01-01
  • Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作

    Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作

    這篇文章主要介紹了Java8中 LocalDate和java.sql.Date的相互轉(zhuǎn)換操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Java中Https發(fā)送POST請求[親測可用]

    Java中Https發(fā)送POST請求[親測可用]

    這篇文章主要介紹了Java中Https發(fā)送POST請求[親測可用],本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • 深入剖析構(gòu)建JSON字符串的三種方式(推薦)

    深入剖析構(gòu)建JSON字符串的三種方式(推薦)

    下面小編就為大家?guī)硪黄钊肫饰鰳?gòu)建JSON字符串的三種方式(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10

最新評論

宝山区| 古交市| 廊坊市| 枞阳县| 六枝特区| 怀集县| 古浪县| 阳曲县| 东辽县| 泰州市| 濮阳市| 虞城县| 东宁县| 游戏| 洪泽县| 恩施市| 厦门市| 漠河县| 河西区| 遵化市| 白银市| 富蕴县| 德格县| 炎陵县| 醴陵市| 扎赉特旗| 东乡族自治县| 蛟河市| 舒兰市| 旺苍县| 大冶市| 棋牌| 得荣县| 邯郸县| 疏勒县| 汤阴县| 伊宁县| 泰兴市| 连州市| 府谷县| 康平县|