欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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

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

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

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

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

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

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

三、具體實(shí)現(xiàn)

Lamp類(lèi):

public enum Lamp {
 /**
  * E2W=East to West, N2S=North to South
  * 從南面的交通燈開(kāi)始,逆時(shí)針執(zhí)行
  */
 //初始狀態(tài)為紅燈
 S2N("N2S","S2W",false),S2W("N2E","E2W",false),
 E2W("W2E","E2S",false),E2S("W2N","S2N",false),
 //對(duì)立面紅燈
 N2E(null,null,false),N2S(null,null,false),
 W2E(null,null,false),W2N(null,null,false),
 //四個(gè)右轉(zhuǎn)方向,始終時(shí)綠燈
 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 對(duì)面的燈
  * @param nexe   下一個(gè)燈 
  * @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í)把對(duì)面的燈設(shè)為綠  下一個(gè)燈設(shè)為紅燈
 public void turnGreen(){
  this.lighted=true;
 
  //如果對(duì)面有燈 
  if(opposite!=null){
   Lamp.valueOf(opposite).turnGreen();
  }
 }
 //紅燈亮  對(duì)立面的燈也變紅
 public Lamp turnRed(){
  this.lighted=false;
  Lamp nextGreenLamp=null;
  //對(duì)面的燈 同步變化
  if(opposite!=null){
   Lamp.valueOf(opposite).turnRed();
  }
  //下一個(gè)燈 綠燈亮 
  if(next!=null){
   nextGreenLamp=Lamp.valueOf(next);
   nextGreenLamp.turnRed();
  }
  return nextGreenLamp;
 }
}

Road類(lèi):

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

LampController類(lèi):

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

運(yùn)行結(jié)果:

四、總結(jié)

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

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

相關(guān)文章

  • java中Properties文件加載和使用方法

    java中Properties文件加載和使用方法

    這篇文章主要為大家詳細(xì)介紹了java中Properties文件加載和使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Spring?Boot騰訊云短信申請(qǐng)與使用示例

    Spring?Boot騰訊云短信申請(qǐng)與使用示例

    這篇文章主要介紹了Spring?Boot騰訊云短信申請(qǐng)與使用,本文通過(guò)實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐

    java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐

    在Java中,實(shí)現(xiàn)角色及菜單權(quán)限管理涉及定義實(shí)體類(lèi)、設(shè)計(jì)數(shù)據(jù)庫(kù)表、實(shí)現(xiàn)服務(wù)層和控制器層,這種管理方式有助于有效控制用戶(hù)權(quán)限,適用于企業(yè)級(jí)應(yīng)用,感興趣的可以一起來(lái)了解一下
    2024-09-09
  • 詳解什么是Java線程池的拒絕策略?

    詳解什么是Java線程池的拒絕策略?

    今天給大家總結(jié)一下線程池的拒絕策略,文中有非常詳細(xì)的介紹及代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • java使用Graphics2D繪圖/畫(huà)圖方式

    java使用Graphics2D繪圖/畫(huà)圖方式

    這篇文章主要介紹了java使用Graphics2D繪圖/畫(huà)圖方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 在Spring Boot中如何使用log4j記錄日志

    在Spring Boot中如何使用log4j記錄日志

    這篇文章主要介紹如何在spring boot中引入log4j,以及一些基礎(chǔ)用法,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02
  • SpringCache框架加載/攔截原理詳解

    SpringCache框架加載/攔截原理詳解

    這篇文章主要介紹了SpringCache框架加載/攔截原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • JVM的類(lèi)加載過(guò)程詳細(xì)說(shuō)明

    JVM的類(lèi)加載過(guò)程詳細(xì)說(shuō)明

    近來(lái)讀了《深入理解JVM虛擬機(jī)》的部分內(nèi)容,對(duì)JVM也慢慢有個(gè)整體的認(rèn)識(shí),今天就來(lái)分享一下我對(duì)JVM類(lèi)加載過(guò)程的學(xué)習(xí)和理解,需要的朋友可以參考下
    2021-06-06
  • 解決for循環(huán)為空不需要判斷的問(wèn)題

    解決for循環(huán)為空不需要判斷的問(wèn)題

    這篇文章主要介紹了解決for循環(huán)為空不需要判斷的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • 兩種用空格分隔的java字符串的方式

    兩種用空格分隔的java字符串的方式

    這篇文章主要介紹了兩種用空格分隔的java字符串的方式的方法,非常簡(jiǎn)單實(shí)用,需要的朋友可以參考下
    2015-03-03

最新評(píng)論