交通灯管理系统

交通灯实际上并不怎么难,就是简单的把这些灯分成几组进行轮换,那些常绿的和长红的不参加轮换。至于东南西北跟灯其实一点关系也没有,灯是不知道东南西北的,这个管理器本身只知道下一组灯是那几个就可以。而在实际的应用方面,常绿的灯也不见得就光是右转,长红的可能有很多,比如交通管理中心对道路进行调度时的调整等等。

张老师的做法并不支持丁字路口之类的特殊路口模式,所以这个管理系统的设计方面应该适合更多种类。

以下是源码

package org.sky.traffic;

import org.dom4j.DocumentException;

public class TrafficApp
{
	public static void main(String[] args) throws DocumentException
	{
		LampManager.getInstance().readConfig("NewFile.xml");
		LampManager.getInstance().start();
		
		/*产生12个方向的路线*/		
		String [] directions = new String[]{
				"s2n","s2w","e2w","e2s","n2s","n2e","w2e","w2n","s2e","e2n","n2w","w2s"		
		};
		for(int i=0;i<directions.length;i++){
			new Road(directions[i]);
		}
	}
}
package org.sky.traffic;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;



public class LampManager
{
	//单例模式的交通灯管理器
	private static LampManager manager = new LampManager();
	private LampManager(){}
	public static final LampManager getInstance()
	{
		return manager;
	}
	
	/* 根据配置文件中的交通灯组进行轮换,最后一组时
	 * 回到第一组,实际上还是循环链表好一些
	 */
	private int groupIndex = 0;
	public void nextGroup()
	{
		String[] curr = lampGroup.get(groupIndex).split(",");
		groupIndex = ++groupIndex == lampGroup.size() ? 0 : groupIndex;
		String[] next = lampGroup.get(groupIndex).split(",");
		System.out.println("==============================================>");
		for (String string : curr)
        {
	        lamps.get(string).nextLampLight();
	        System.out.print(string + " ");
        }
		System.out.println("blackout");
		
		for (String string : next)
        {
	        lamps.get(string).nextLampLight();
	        System.out.print(string + " ");
        }
		System.out.println("lighted");
		
	}
	
	/* 检查灯是否绿灯 */
	public boolean isLighted(String key)
	{
		return lamps.get(key).isLighted();
	}
	
	/* 启动交通灯管理器 */
	public void start()
	{
		ScheduledExecutorService timer =  Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable()
		{
			public  void run()
			{
				nextGroup();
			}
		},10,10,TimeUnit.SECONDS);
		System.out.println("==============================================>");
		System.out.println("e2s w2n lighted");
	}
	
	/* 一个灯的集合用来查询灯的情况 */
	private HashMap<String, Lamp> lamps = new HashMap<String, Lamp>(12);
	/* 屏蔽列表其实没有真正实现,其实应该在常绿和长红的灯不参见轮换
	 * 现在这种做法只是通过不写进配置文件来达到的
	 */
	private ArrayList<String> alwaysGreen = new ArrayList<String>();
	private ArrayList<String> alwaysRed = new ArrayList<String>();
	private ArrayList<String> lampGroup = new ArrayList<String>();
	
	/**
	 * 读取交通灯配置文件
	 * 该方法依赖于Dom4j框架
	 */
	public void readConfig(String fileName) throws DocumentException
	{
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File(fileName));
		Element root = document.getRootElement();  
		
		Element lampList = root.element("LampList");
		for (Iterator<Element> iterator = lampList.elementIterator(); iterator.hasNext();)
        {
	        Element lamp = iterator.next();
	        String name = lamp.attribute("name").getValue();
	        boolean lighted = Boolean.parseBoolean(lamp.attribute("lighted").getValue());
	        lamps.put(name, new Lamp(lighted));
        }
		
		/*
		 * 初始化始终为绿灯的列表
		 */
		Element alwaysGreen = root.element("AlwaysGreen");
		String[] greens = alwaysGreen.getText().split(",");
		for (String string : greens)
        {
	        this.alwaysGreen.add(string);
	    }
		
		/*
		 * 初始化始终为红灯的列表
		 */
		Element alwaysRed = root.element("AlwaysRed");
		String[] reds = alwaysRed.getText().split(",");
		for (String string : reds)
        {
			if(!"".equals(string))
			{
	        	this.alwaysRed.add(string);
	        }
        }
		
		//初始化交通组轮换组
		Element lampGroup = root.element("LampGroup");
		for (Iterator<Element> iterator = lampGroup.elementIterator(); iterator.hasNext();)
        {
	        String group = iterator.next().getText();
	        this.lampGroup.add(group);
        }
	}
}


package org.sky.traffic;

public class Lamp
{
	private boolean lighted;
	
	
    public Lamp(boolean lighted)
    {
    
	    this.lighted = lighted;
    }
	
	public boolean isLighted()
	{
		return lighted;
	}
	
	public void nextLampLight()
	{
		lighted = !lighted;
	}
}

package org.sky.traffic;

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 = null;
	
	public Road(String name)
	{
	
		this.name = name;
		
		// 模拟车辆不断随机上路的过程
		ExecutorService pool = Executors.newSingleThreadExecutor();
		pool.execute(new Runnable()
		{
			
			public void run()
			{
			
				for (int i = 1; i < 1000; i++)
				{
					try
					{
						Thread.sleep((new Random().nextInt(10) + 1) * 1000);
					}
					catch (InterruptedException e)
					{
						e.printStackTrace();
					}
					vechicles.add(Road.this.name + "_" + i);
				}
			}
			
		});
		
		// 每隔一秒检查对应的灯是否为绿,是则放行一辆车
		ScheduledExecutorService timer = Executors.newScheduledThreadPool(1);
		timer.scheduleAtFixedRate(new Runnable()
		{
			
			public void run()
			{
				if (vechicles.size() > 0)
				{
					boolean lighted = LampManager.getInstance().isLighted(vechicles.get(0).substring(0,3));
					if (lighted)
					{
						System.out.println(vechicles.remove(0) + " is traversing !");
					}
				}
				
			}
		}, 1, 1, TimeUnit.SECONDS);
		
	}
}

配置文件NewFile.xml
<?xml version="1.0" encoding="UTF-8"?>
<TrafficLamp>
	<LampList>
		<Lamp name="e2n" lighted="true"/>
	    <Lamp name="n2w" lighted="true"/>
	    <Lamp name="w2s" lighted="true"/>
	    <Lamp name="s2e" lighted="true"/>
	    <Lamp name="e2s" lighted="true"/>
	    <Lamp name="w2n" lighted="true"/>
	    <Lamp name="s2w" lighted="false"/>
	    <Lamp name="n2e" lighted="false"/>
	    <Lamp name="e2w" lighted="false"/>
	    <Lamp name="w2e" lighted="false"/>
	    <Lamp name="s2n" lighted="false"/>
	    <Lamp name="n2s" lighted="false"/>    
	</LampList>
    
    <AlwaysGreen>e2n,n2w,w2s,s2e</AlwaysGreen>
    <AlwaysRed></AlwaysRed>
    <LampGroup>
        <Group>e2s,w2n</Group>
        <Group>s2w,n2e</Group>
        <Group>e2w,w2e</Group>
        <Group>s2n,n2s</Group>
    </LampGroup>
</TrafficLamp>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值