交通灯管理系统

今天看了张孝祥老师的“交通灯管理系统”的题目和解决方案,尝试着再自己分析这个场景,实现不一定很好,权当学习了。

首先提取下这个问题的关键要素:交通灯,路,车。三者的一种关系是车可以认为是路的“元素”,车的通过和增加都是由路负责管理的。而每一个十字路口的放行与否,都是通过交通灯控制的。路和灯应该是归属的关系,一个十字路口“拥有”一个交通灯系统。

所以我们抽象交通灯这个类,因为向右是永远放行的,所以我们可以忽略向右的这条线路,而相反方向的灯的变化是完全相同的,所以可以抽象为一个管理系统,这样其实一个路口的交通等的状态就只有4种了,而且这四种同一时刻只有一个是放行的状态。

用枚举实现交通灯:

 1 package traffic;

 2 

 3 public enum Lamp {

 4     NSStraight, NSTurn, EWStraight, EWTurn;

 5     

 6     private boolean green = false;

 7 

 8     public boolean isGreen() {

 9         return green;

10     }

11 

12     public void lighteOn() {

13         this.green = true;

14         System.out.println(this.toString());

15     }

16     public void lightOff(){

17         this.green = false;

18     }

19 

20     Lamp nextLamp() {

21         switch (this) {

22         case NSStraight:

23             lightOff();

24             NSTurn.lighteOn();

25             return NSTurn;

26         case NSTurn:

27             lightOff();

28             EWStraight.lighteOn();

29             return EWStraight;

30         case EWStraight:

31             lightOff();

32             EWTurn.lighteOn();

33             return EWTurn;

34         case EWTurn:

35             lightOff();

36             NSStraight.lighteOn();

37             return NSStraight;

38         }

39         return null;

40     }

41     @Override

42     public String toString(){

43         switch (this) {

44         case NSStraight:

45             return "----------南北方向直行";

46         case NSTurn:

47             return "----------南北方向左转";

48         case EWStraight:

49             return "----------东西方向直行";

50         case EWTurn:

51             return "----------东西方向左转";

52         }

53         return null;

54         

55     }

56 }

交通灯的轮换相对来说比较独立,和路的耦合不算大,每个路口可以独立于路配备一个交通灯,这里先用线程实现模拟交通灯的切换规则:

 1 package traffic;

 2 

 3 public class LampControl implements Runnable{

 4     Lamp NSStraight = Lamp.NSStraight;

 5     Lamp NSTurn = Lamp.NSTurn;

 6     Lamp EWStraight = Lamp.EWStraight;

 7     Lamp EWTurn = Lamp.EWTurn;

 8     

 9     Lamp currentLamp = NSStraight;

10     

11     public Lamp getCurrentLamp() {

12         return currentLamp;

13     }

14     

15     int StraightTime = 10000;//ms

16     int TurnTime = 10000;

17     @Override

18     public void run() {

19         currentLamp.lighteOn();

20         while(true){

21             try {

22                 Thread.sleep(StraightTime);

23                 currentLamp = currentLamp.nextLamp();

24                 Thread.sleep(TurnTime);

25                 currentLamp = currentLamp.nextLamp();

26                 Thread.sleep(StraightTime);

27                 currentLamp = currentLamp.nextLamp();

28                 Thread.sleep(TurnTime);

29                 currentLamp = currentLamp.nextLamp();

30                 

31             } catch (InterruptedException e) {

32                 e.printStackTrace();

33             }

34         }

35         

36         

37     }

38     

39 }

这样在主函数中可以通过独立的线程模拟单独的交通灯切换功能。

接下来模拟十字路口的车辆过往的展示,一个十字路口有一个交通灯系统,抛开向右自由行驶的路线,有8条行车路线,每条路线用一个集合存放这条路线上的车,适当的时候放行。

 1 package traffic;

 2 

 3 import java.util.ArrayList;

 4 import java.util.List;

 5 

 6 public enum SingleRoad {

 7     NSRoad, SNRoad, NSLRoad, SNLRoad, EWRoad, WERoad, EWLRoad, WELRoad;

 8     int num = 1;

 9     List<Integer> list = new ArrayList<Integer>();

10 

11     public void addCar() {

12         this.list.add(num++);

13             System.out.println(this.toString()+": "+num + "号车正在等待");

14     }

15 

16     public void passCar() {

17         if(this.list.size()>0){

18             Integer i = this.list.remove(0);

19             System.out.println(this.toString()+": "+ i + "号车正在过马路");

20         }

21     }

22 

23     @Override

24     public String toString() {

25         switch (this) {

26         case NSRoad:

27             return "北向南";

28         case SNRoad:

29             return "南向北";

30         case NSLRoad:

31             return "北向南左";

32         case SNLRoad:

33             return "南向北左";

34         case EWRoad:

35             return "东向西";

36         case WERoad:

37             return "西向东";

38         case EWLRoad:

39             return "东向西左";

40         case WELRoad:

41             return "西向东左";

42         }

43         return null;

44     }

45 

46 }

在创建一个Road类管理一个十字路口的情形,随机的往每条线路上增加车辆并等待,当这条线路的控制灯亮的时候,放行这条线路上的车。

 1 package traffic;

 2 

 3 import java.util.ArrayList;

 4 import java.util.List;

 5 import java.util.Random;

 6 

 7 public class Road implements Runnable {

 8     LampControl lc = new LampControl();

 9     List<SingleRoad> listRoads = new ArrayList<SingleRoad>();

10     SingleRoad NSRoad = SingleRoad.NSRoad;

11     SingleRoad SNRoad = SingleRoad.SNRoad;

12     SingleRoad NSLRoad = SingleRoad.NSLRoad;

13     SingleRoad SNLRoad = SingleRoad.SNLRoad;

14     SingleRoad EWRoad = SingleRoad.EWRoad;

15     SingleRoad WERoad = SingleRoad.WERoad;

16     SingleRoad EWLRoad = SingleRoad.EWLRoad;

17     SingleRoad WELRoad = SingleRoad.WELRoad;

18 

19     public Road(LampControl lc) {

20         this.lc = lc;

21         listRoads.add(NSRoad);

22         listRoads.add(NSLRoad);

23         listRoads.add(SNRoad);

24         listRoads.add(SNLRoad);

25         listRoads.add(EWLRoad);

26         listRoads.add(EWRoad);

27         listRoads.add(WELRoad);

28         listRoads.add(WERoad);

29     }

30 

31     void method(){

32         while(true){

33             Lamp l = lc.getCurrentLamp();

34             switch (l) {

35             case NSStraight:

36                 NSRoad.passCar();

37                 SNRoad.passCar();

38                 passTime();

39                 break;

40             case NSTurn:

41                 NSLRoad.passCar();

42                 SNLRoad.passCar();

43                 passTime();

44                 break;

45             case EWStraight:

46                 EWRoad.passCar();

47                 WERoad.passCar();

48                 passTime();

49                 break;

50             case EWTurn:

51                 EWLRoad.passCar();

52                 WELRoad.passCar();

53                 passTime();

54                 break;

55             }

56         }

57         

58     }

59     

60     private void passTime(){

61         try {

62             //一秒过一辆

63             Thread.sleep(1000);

64         } catch (InterruptedException e) {

65             e.printStackTrace();

66         }

67     }

68     

69     @Override

70     public void run() {

71         while (true) {

72             try {

73                 //1--3秒随机添加一辆车

74                 Thread.sleep((new Random().nextInt(3) + 1) * 1000);

75             } catch (InterruptedException e) {

76                 e.printStackTrace();

77             }

78             int index = new Random().nextInt(8);

79             SingleRoad sr = listRoads.get(index);

80             sr.addCar();

81         }

82 

83     }

84 

85 }

这样当我们实际运行的时候就有三个线程了,一个线程专门负责灯的转换,一个线程专门负责车的添加,一个线程负责灯亮的时候车的放行。

1 public static void main(String[] args) {

2         LampControl lc1 = new LampControl();

3         Road road = new Road(lc1);

4         new Thread(lc1).start();

5         new Thread(road).start();

6         road.method();

7     }

有了张老师对整体思路的分析,自己沿着老师的思维走了一遍,收货颇多。

你可能感兴趣的:(交通)