学习了好多天,总结一下这个项目:
交通灯管理项目模拟了对十字路口交通灯的控制,一般在我们生活中的十字路口是有人行道的,而此项目没有考虑人行道,到下面需求的第3条,右转车辆不受信号灯控制可以看出。
业务需求分析:
1、具体信号灯控制逻辑与现实生活中普通交通灯控制逻辑相同,不考虑特殊情况下的控制逻辑。
注:南北向车辆与东西向车辆交替放行,同方向等待车辆应先放行直行车辆而后放行左转车辆。
每辆车通过路口时间为1秒(提示:可通过线程Sleep的方式模拟)。随机生成车辆时间间隔以及红绿灯交换时间间隔自定,可以设置。2、信号灯忽略黄灯,只考虑红灯和绿灯
2、异步随机生成按照各个路线行驶的车辆。由南向而来去往北向的车辆 ---- 直行车辆,,由西向而来去往南向的车辆 ---- 右转车辆, 由东向而来去往南向的车辆 ---- 左转车辆
3、应考虑左转车辆控制信号灯,右转车辆不受信号灯控制。
4、每辆车通过路口的时间为1秒
5、随机生成车辆的时间间隔,以及红绿灯交换时间间隔自定,可以设置
主要代码如下:
Road类
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Random;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ScheduledExecutorService;
- import java.util.concurrent.TimeUnit;
- public class Road {
- // 保存车辆的集合
- private List<String> vechicles = new ArrayList<String>();
- // 车辆的名字
- private String name;
- public Road(String name) {
- this.name = name;
- // 在线程池中选择空闲的线程,执行模拟车辆不断随机上路的过程
- Executors.newSingleThreadExecutor().execute(
- new Runnable() {
- @Override
- public void run() {
- // 车辆上路是随机的,所以需要一个随机数产生器
- Random r = new Random();
- // 模拟一千辆车上路
- for (int i = 1; i < 1000; i++) {
- try {
- // 没产生一辆车,线程随机睡眠一段时间
- Thread.sleep(r.nextInt(11) * 1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // 把产生的车放进集合中
- vechicles.add(Road.this.name + "_" + i);
- }
- }
- });
- // 获得一个调度线程池
- ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
- // 执行定时器
- timer.scheduleAtFixedRate(
- // 需要执行的代码
- new Runnable() {
- @Override
- public void run() {
- // 路上有车时才执行逻辑
- if (vechicles.size() > 0) {
- // 判断与这个类对应的交通灯是否亮着
- boolean lighted = Lamp.valueOf(Road.this.name)
- .isLighted();
- if (lighted) {
- // 如果亮着,路前面的车辆就可以走了,也就是把集合中索引为0的代表汽车的String对象移除,并打印出来
- System.out.println(vechicles.remove(0));
- }
- }
- }
- },
- 1, // 一秒后启动这个定时器
- 1,// 每隔一秒执行一次
- TimeUnit.SECONDS);// 时间单位设置为秒
- }
- }
BankTest主类
01./*
02.
03.1、用for循环创建出4个普通窗口,再创建出1个快速窗口和一个VIP窗口。
04.2、再创建三个定时器,分别定时去创建新的普通客户号码、新的快速客户号码、新的VIP客户号码。
05.
06. */
07.
08.import java.util.concurrent.Executors;
09.import java.util.concurrent.TimeUnit;
10.
11.public class BankTest {
12. public static void main(String[] args) {
13. // 产生4个普通窗口
14. for (int i = 1; i < 5; i++) {
15. ServiceWindow window = new ServiceWindow();
16. window.setWindowId(i);
17. window.start();
18. }
19.
20. // 产生1个快速窗口
21. ServiceWindow expressWindow = new ServiceWindow();
22. expressWindow.setType(CustomerType.EXPRESS);
23. expressWindow.start();
24.
25. // 产生一个VIP窗口
26. ServiceWindow vipWindow = new ServiceWindow();
27. vipWindow.setType(CustomerType.VIP);
28. vipWindow.start();
29.
30. // 普通客户拿号
31. Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
32. public void run() {
33. // 创建线程,运行普通客户服务
34. Integer serviceNumber = NumberMachine.getInstance()
35. .getCommnManager().generateNewManager();
36. System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
37. }
38. }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);
39. // 快速客户拿号
40. Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
41. public void run() {
42. // 创建线程,运行快速客户服务
43. Integer serviceNumber = NumberMachine.getInstance()
44. .getExpressManager().generateNewManager();
45. System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
46. }
47. }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);
48. // VIP客户拿号
49. Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
50. public void run() {
51. // 创建线程,运行VIP客户服务
52. Integer serviceNumber = NumberMachine.getInstance()
53. .getVipManager().generateNewManager();
54. System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
55. }
56. }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);
57. }
58.}
NumberMachine类
01./*
02.
03.1、定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速和VIP客户的号码管理器,定义三个对应的方法来返回这三个NumberManager对象。
04.2、将NumberMachine类设计成单例。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。
05.
06. */
07.
08.//创建号码管理器类
09.public class NumberMachine {
10. // 设计单列
11. // 私有构造函数
12. private NumberMachine() {
13. }
14.
15. private static NumberMachine instance = new NumberMachine();
16.
17. // 公有静态方法,返回这个单例对象的引用
18. public static NumberMachine getInstance() {
19. return instance;
20. }
21.
22. // 创建三种客户产生号码的机器
23. private NumberManager commnManager = new NumberManager();
24. private NumberManager expressManager = new NumberManager();
25. private NumberManager vipManager = new NumberManager();
26.
27. // 产生get方法,获取对象
28. public NumberManager getCommnManager() {
29. return commnManager;
30. }
31.
32. public NumberManager getExpressManager() {
33. return expressManager;
34. }
35.
36. public NumberManager getVipManager() {
37. return vipManager;
38. }
39.}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
// 保存车辆的集合
private List<String> vechicles = new ArrayList<String>();
// 车辆的名字
private String name;
public Road(String name) {
this.name = name;
// 在线程池中选择空闲的线程,执行模拟车辆不断随机上路的过程
Executors.newSingleThreadExecutor().execute(
new Runnable() {
@Override
public void run() {
// 车辆上路是随机的,所以需要一个随机数产生器
Random r = new Random();
// 模拟一千辆车上路
for (int i = 1; i < 1000; i++) {
try {
// 没产生一辆车,线程随机睡眠一段时间
Thread.sleep(r.nextInt(11) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 把产生的车放进集合中
vechicles.add(Road.this.name + "_" + i);
}
}
});
// 获得一个调度线程池
ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
// 执行定时器
timer.scheduleAtFixedRate(
// 需要执行的代码
new Runnable() {
@Override
public void run() {
// 路上有车时才执行逻辑
if (vechicles.size() > 0) {
// 判断与这个类对应的交通灯是否亮着
boolean lighted = Lamp.valueOf(Road.this.name)
.isLighted();
if (lighted) {
// 如果亮着,路前面的车辆就可以走了,也就是把集合中索引为0的代表汽车的String对象移除,并打印出来
System.out.println(vechicles.remove(0));
}
}
}
},
1, // 一秒后启动这个定时器
1,// 每隔一秒执行一次
TimeUnit.SECONDS);// 时间单位设置为秒
}
}
总结: 从这个项目中我又复习了java基础知识, 虽然各个部分学的好 但是你不一定用得好, 合起来就不行了, 还是要多学多练 光知道概念是不行的. 多动手桥代码才是硬道理.