交通燈管理系統

交通燈實際上並不怎麼難,就是簡單的把這些燈分成幾組進行輪換,那些常綠的和長紅的不參加輪換。至於東南西北跟燈其實一點關係也沒有,燈是不知道東南西北的,這個管理器本身只知道下一組燈是那幾個就可以。而在實際的應用方面,常綠的燈也不見得就光是右轉,長紅的可能有很多,比如交通管理中心對道路進行調度時的調整等等。

張老師的做法並不支持丁字路口之類的特殊路口模式,所以這個管理系統的設計方面應該適合更多種類。

以下是源碼

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>


發佈了49 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章