首先先弄明白在十字路口车的行驶路线,看着张老师这个图就很清楚了的
最后总结项目的大概思路
路:有线程池,可以向路上添加车。有定时器,如果灯是亮的就让车1秒钟过去一个
灯:有12个灯。有对面的灯,下一个灯,灯的状态。有变亮和变暗的方法。
灯的控制器:有定时器,将灯变亮并且10秒钟将灯切换到下一个
/*首先要知道有几个类
路,灯
开始总认为车也是一个类,但是车没有什么动作,其实他只是路中的一个成员变量,
是路在操纵着车的到来和离开。可以将车放入一个集合中去,当可以过路口的时候
就直接将集合中的车的第一辆删除即可(remove(0))
现在思考路。一个十字路口,将会有12条不同的路线,每条路线都会有自己的车成员,
可以增加和减少车。那么就要想到线程
写一个路的类*/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Road {
List<String> vechicles = new ArrayList<String>();
private String name=null;
public Road(String name) {
this.name = name;
//返回一个线程池
ExecutorService pool=Executors.newSingleThreadExecutor();
//创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程
pool.execute(new Runnable() {
//在未来某个时间执行给定的命令。
@Override
public void run() {
for(int i=1;i<1000;i++)
{
try {
Thread.sleep((int)(Math.random()*10000+1));//(int)(Math.random()*10000+1)
} catch (InterruptedException e) {
e.printStackTrace();
}
vechicles.add(Road.this.name+"_"+i);//这里在调用外部类的局部变量,可以使用类名.this.变量名。也可以将局部变量final
}
}
});
//定时器
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
//在未来某个时间执行给定的命令。()中的参数:池中所保存的线程数,即使线程是空闲的也包括在内。
/*创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;也就是将在 initialDelay 后开始执行,
然后在 initialDelay+period 后执行,接着在 initialDelay + 2 * period 后执行,依此类推。
*.scheduleAtFixedRate(command, initialDelay, period, unit)
参数:
command - 要执行的任务
initialDelay - 首次执行的延迟时间
period - 连续执行之间的周期
unit - initialDelay 和 period 参数的时间单位 */
timer.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
if(vechicles.size()>0){//必须要先查看这条路上是否有车,要不然会出现很诡异的结果
boolean lighted=Lamp.valueOf(Road.this.name).isLighted();
if(lighted)
{
//vechicles.remove(0)返回的是那个remove的对象
System.out.println(vechicles.remove(0).toString()+" 过了十字路口");
}
}
}
},
1,
1,
TimeUnit.SECONDS);
}
}
//这其中创建线程池和创建定时器是最主要的,线程池来定时向每条路上增加车。定时器是来规定每隔多长时间一辆车过了路口(1秒钟后继续执行)
//==================================================================================
//然后就是红绿灯了,这里一共有12条路,所以要设计12盏灯(每盏灯是亮(绿)或不亮(红)),所以这里使用枚举
package com.traffic;
//枚举
public enum Lamp {
S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false),
N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false),
S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true);
// S2E(null,null,false),E2N(null,null,false),N2W(null,null,false),W2S(null,null,false);
private Lamp(String opposite,String next,boolean lighted)
{
this.opposite=opposite;
this.next=next;
this.lighted=lighted;
}
//灯的状态
private boolean lighted;
//灯对应的灯
private String opposite;//因为在构造函数的时候需要使用到后面的定义的Lamp,但是前面使用后面定义的Lamp会报错的,
//所以将这里的Lamp类型变成String类型,在使用时在用枚举的valueOf获得到
private String next;
public boolean isLighted()
{
return lighted;
}
public void light()
{
this.lighted=true;
if(opposite!=null){//灯对应的灯如果不为null的话就会死循环的,所以S2N对应的灯是N2S,N2S对应的灯是null
// Lamp.valueOf(opposite).lighted=true;//这里做完后实验,将opposite.lighted=true,试试看是否不会死循环(实验不会)
Lamp.valueOf(opposite).light();
}
System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");
}
public Lamp blackOut()
{
this.lighted=false;
if(opposite!=null){//把对应的灯变黑
// Lamp.valueOf(opposite).lighted=false;
Lamp.valueOf(opposite).blackOut();
}
Lamp nextLamp=null;
if(next!=null)//把下一个灯变亮
{
nextLamp=Lamp.valueOf(next);
System.out.println("绿灯从" + name() + "-------->切换为" + next);
nextLamp.light();
}
return nextLamp;//返回下一个灯
}
}
//在红绿灯中有一个将灯变亮的方法,一个将灯边暗的方法,并且可以知道自己所对应的灯是谁,自己的下一个灯是谁,自己现在的状态(是亮是暗)
//=======================================================================================
//写一个可以控制灯的控制器,让他在一定时间后可以变亮,对应的灯也变亮,在变暗的时候,下一个灯可以变亮,就这样循环着
package com.traffic;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LampController {
private Lamp currentLamp;
public LampController()
{
currentLamp=Lamp.S2N;
currentLamp.light();
//定时器
ScheduledExecutorService timer=Executors.newScheduledThreadPool(1);
timer.scheduleAtFixedRate(
new Runnable() {
@Override
public void run() {
System.out.println("切换一次");
currentLamp=currentLamp.blackOut();
}
},
10, //每隔10s将灯变黑
10, //10s一次循环
TimeUnit.SECONDS);
}
}
//最后写一个主类,可以调用他们。创建12条路,并创建出灯的控制器,这样,交通灯管理系统就做好了
//通过这个交通灯管理系统项目,我复习了枚举,线程的知识,了解了交通灯java思想。同时还学会了有关定时器的知识。努力啊
复习时看着这个图就能很轻松的写下代码