欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 多線程交通信號(hào)燈模擬過程詳解

 更新時(shí)間:2019年07月04日 14:59:33   作者:huxinjianzs  
這篇文章主要介紹了java 多線程交通信號(hào)燈模擬過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

這學(xué)期我們java課程的課程設(shè)計(jì)項(xiàng)目----交通信號(hào)燈的線程設(shè)計(jì)

  • 實(shí)驗(yàn)?zāi)康模憾嗑€程設(shè)計(jì),同步機(jī)制
  • 題意 設(shè)計(jì)一個(gè)交通信號(hào)燈類:
    • 變量:位置、顏色(紅、黃、綠)、顯示時(shí)間(秒)。
    • 方法:切換信號(hào)燈。
  • 創(chuàng)建并啟動(dòng)兩個(gè)線程(東西向、南北向)同時(shí)運(yùn)行。
  •  實(shí)驗(yàn)要求
    • 設(shè)計(jì)線程。
    • 設(shè)計(jì)路口信號(hào)燈示意圖界面。
    • 進(jìn)一步將每個(gè)方向的信號(hào)燈分成3種車道燈:左轉(zhuǎn)、直行和右轉(zhuǎn)。
    • 根據(jù)車流量進(jìn)行時(shí)間的模糊控制。

在課程設(shè)計(jì)的開始并沒有仔細(xì)看老師的要求,只知道是交通信號(hào)燈。然后就開始各種找資料,百度,網(wǎng)上大量的關(guān)于紅綠燈的設(shè)計(jì)都是參考張孝祥老師的教程,大概的設(shè)計(jì)方法是創(chuàng)建了三個(gè)類 lamp、road、lampcontrol。

然鵝......對(duì).....然鵝又來了,在查了大概兩天資料后,我又反過來看了一遍老師發(fā)的設(shè)計(jì)要求.....這這這.....,光控制燈就行了啊,不要車的啊,捂臉...

所以設(shè)計(jì)思路馬上就變得清晰,根據(jù)張老師的做法,每個(gè)路口都有三個(gè)燈,分別為左轉(zhuǎn)、直行、右轉(zhuǎn),所以一共有12盞燈。按照要求,右轉(zhuǎn)燈為常亮燈,左轉(zhuǎn)和直行燈才有紅綠交替。在除去右轉(zhuǎn)燈的八個(gè)燈里面,又可以分為四組可以兩兩匹配的燈,分別為東西左轉(zhuǎn)南北(平行轉(zhuǎn)垂直)、南北直行(垂直通行)、南北左轉(zhuǎn)東西(垂直轉(zhuǎn)平行)、東西直行(平行通行)。

于是我給這個(gè)12個(gè)燈編了個(gè)號(hào):

emmm 大概就是這樣,但是跟生活中的紅綠燈不同,生活中的都是看對(duì)面路口的燈,我們這里是模擬嘛....就各個(gè)路口用各個(gè)路口的燈唄.....

大致解釋一下,

1號(hào)燈為由南向西的左轉(zhuǎn)燈,2號(hào)燈為由南向北的直行燈,3號(hào)燈為由南向東的右轉(zhuǎn)燈。

4號(hào)燈為由東向北的右轉(zhuǎn)燈,5號(hào)燈為由東向西的直行燈,6號(hào)燈為由東向南的左轉(zhuǎn)燈。

7號(hào)燈為由北向西的右轉(zhuǎn)燈,8號(hào)燈為由北向南的直行燈,9號(hào)燈為由北向東的左轉(zhuǎn)燈。

10號(hào)燈為由西向北的左轉(zhuǎn)燈,11號(hào)燈為由西向東的直行燈,12號(hào)燈為由西向南的右轉(zhuǎn)燈。

然后根據(jù)匹配的原則,大概就是這么一張圖:

我們就可以得到:

這四組信號(hào)燈。

到這里我們思路就很清晰了,我們可以分別為每一組信號(hào)燈開一個(gè)進(jìn)程,然后使四個(gè)進(jìn)程循環(huán)交替進(jìn)行就實(shí)現(xiàn)了綠燈的轉(zhuǎn)換。使用了程的同步技術(shù)。

當(dāng)然,我們都已經(jīng)開了四個(gè)進(jìn)程了,為了錦上添花,我當(dāng)然不介意再加個(gè)小車了hhhhhh

實(shí)驗(yàn)結(jié)果圖:

源代碼:

light類:

package traffic;
 public class light {
	int x,y;         //燈在畫布上的位置
	boolean status;      //燈的狀態(tài)
	public light(int x,int y,boolean islight) {
		this.x=x;        
		this.y=y;
		this.status=islight;
	}
	public void setlight(boolean sta) {    //對(duì)外接口更改燈的狀態(tài)
		this.status=sta;
	}
}

lamp類:

package traffic;
 public class lamp implements Runnable {
	light opposite, now;      //相互匹配的兩個(gè)燈
	int greentime;         //綠燈亮的時(shí)間
	int name;            //編組
	boolean status;         //狀態(tài)
	static Object lock = new Object();
 
	public lamp(light l0, light l2,int gt, boolean st, int name) {
		now = l0;
		opposite = l2;
		status = st;
		greentime = gt;
		this.name = name;
		lightstatues();
	}
 
	public void change() { 
		this.status = !(this.status);
		lightstatues();
	}
	public void setgreentime(int time) {
		this.greentime=time;
	}
	public int getgreentime() {
		return this.greentime;
	}
	public void lightstatues() {
		opposite.setlight(status);
		now.setlight(status);
	}
 
	public void run() {
		while (true) {
			synchronized (lock) {        //使用synchronized實(shí)現(xiàn)進(jìn)程間的互斥
				if (name == mainclass.panel.islight) {      //使用輔助變量實(shí)現(xiàn)進(jìn)程按順序循環(huán)
					//System.out.println("now is: "+name);
					change();
					mainclass.panel.repaint();
					try {
						Thread.sleep(greentime);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					lock.notifyAll();        //喚醒其他進(jìn)程
					change();
					mainclass.panel.LampChange();
					mainclass.panel.repaint();
					try {
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} else {
					try {
						lock.wait();      //掛起進(jìn)程
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}

Mypanel類:

package traffic;
 
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JPanel;
public class Mypanel extends JPanel {
	light l0,l2,l3,l4,l5,l6,l7,l8,l9,l10,l11,l12;   //十二個(gè)燈
	lamp lamp1,lamp2,lamp3,lamp4;           //四組信號(hào)燈
	static int islight;                //實(shí)現(xiàn)進(jìn)程循環(huán)的輔助變量
	Random r=new Random();
	static public ArrayList<light> lightlist= new ArrayList<light>();  //使用list方便遍歷每個(gè)燈
	static public ArrayList<car> carlist= new ArrayList<car>();          //方便遍歷每個(gè)車
	public Mypanel() {
		// TODO Auto-generated constructor stub
		l0=addlist(l0, 212, 316, false);
		l2=addlist(l2, 242, 316, false);	
		l3=addlist(l3, 272, 316, true);	
		l4=addlist(l4, 316, 116, true);	
		l5=addlist(l5, 316, 146, false);	
		l6=addlist(l6, 316, 176, false);	
		l7=addlist(l7,116 , 70, true);	
		l8=addlist(l8, 146, 70, false);	
		l9=addlist(l9, 176, 70, false);	
		l10=addlist(l10, 70, 212, false);	
		l11=addlist(l11, 70, 242, false);	
		l12=addlist(l12, 70, 272, true		
		lamp1=new lamp(l9,l0,2000,false,0);
		lamp2=new lamp(l11,l5,2000,false,1);
		lamp3=new lamp(l10,l6,2000,false,2);
		lamp4=new lamp(l8,l2,2000,false,3);
 		islight = 0 ;		
		Thread t1=new Thread(lamp1);      //創(chuàng)建并啟動(dòng)線程
		Thread t2=new Thread(lamp2);
		Thread t3=new Thread(lamp3);
		Thread t4=new Thread(lamp4);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
	light addlist(light a,int x,int y,boolean sta) {
		a=new light(x,y,sta);
		lightlist.add(a);
		return a;
	}
	public void addcar() {          //生成小車
		int now,next;
		now=r.nextInt(4);
		next=r.nextInt(4);
		car testcar=null;
		while(now==next) 
			next=r.nextInt(4);
		switch(now) {
		case 0:
			testcar=new car(now,next,l0,l2,l3);
			break;
		case 1:
			testcar=new car(now,next,l6,l5,l4);
			break;
		case 2:
			testcar=new car(now,next,l9,l8,l7);
			break;
		case 3:
			testcar=new car(now,next,l10,l11,l12);
			break;
		}
		carlist.add(testcar);
		Thread catt=new Thread(testcar);
		catt.start();
	}
	public void LampChange() {
		islight=(islight+1)%4;
	}
	public void paint(Graphics g) {
		super.paint(g);
		
		g.setColor(Color.darkGray);    //畫路
		g.fillRect(0, 100, 400, 6);
		g.fillRect(0, 300, 400, 6);
		g.fillRect(100, 0, 6, 400);
		g.fillRect(300, 0, 6, 400);
		g.setColor(Color.gray);
		g.fillRect(0, 200, 400, 2);
		g.fillRect(200, 0, 2, 400);
		g.setColor(Color.blue);	
		g.setColor(Color.black);     //畫信號(hào)燈板
		g.fillRect(202,306, 100, 40);
		g.fillRect(306,106, 40, 100);
		g.fillRect(106,60, 100, 40);
		g.fillRect(60,202,40, 100);
		light temp;
		car buf;
		for(int i=0;i<carlist.size();i++) {   //畫車
			buf=carlist.get(i);
			g.setColor(Color.BLUE);
			g.fillRect(buf.x, buf.y, 50, 50);
		}
		for(int i=0;i<lightlist.size();i++) {    //畫燈
			temp=lightlist.get(i);
			if(temp.status)
				g.setColor(Color.green);
			else
				g.setColor(Color.RED);
			g.fillOval(temp.x, temp.y, 20, 20);
		}
	}
}

welcomepanel類:

package traffic; 
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel; 
public class welcomepanel extends JPanel implements Runnable{  //開始界面
	int info = 0;
	Boolean isLive=true; 
	public void paint(Graphics g) {
		super.paint(g);
		g.fillRect(0, 0, 420,450);
		g.setColor(Color.red);
		g.setFont(new Font("微軟雅黑", Font.BOLD, 30));
		if (info % 2 == 0) {
			g.drawString("多線程紅綠燈模擬", 80, 150);
		}
	}
 
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			info++;
			this.repaint();
			if (isLive == false) {
				break;
			}
		}
	}	
}

set類:

package traffic; 
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField; 
public class set extends JFrame implements ActionListener {   //設(shè)置界面
  JLabel lab1,lab2,lab3,lab4;
  JTextField jtext1,jtext2,jtext3,jtext4;
  JPanel panel1,panel2,panel3,panel4;
  JButton jb1,jb2;
  int time1,time2,time3,time4;
	public set(){ 
  	lab1=new JLabel("南北左轉(zhuǎn)東西:");
  	lab2=new JLabel("東西直行:");
  	lab3=new JLabel("東西左轉(zhuǎn)南北:");
  	lab4=new JLabel("南北直行:");
  	time1=mainclass.panel.lamp1.getgreentime();
  	time2=mainclass.panel.lamp2.getgreentime();
  	time3=mainclass.panel.lamp3.getgreentime();
  	time4=mainclass.panel.lamp4.getgreentime();
  	jtext1=new JTextField(String.valueOf(time1));
  	jtext2=new JTextField(String.valueOf(time2));
  	jtext3=new JTextField(String.valueOf(time3));
  	jtext4=new JTextField(String.valueOf(time4));
  	
  	jb1=new JButton("確定");
  	jb1.addActionListener(this);
  	jb2=new JButton("取消");
  	jb2.addActionListener(this);  	
  	this.setLayout(new GridLayout(5,2,10,5));
  	this.add(lab1);
  	this.add(jtext1);
  	this.add(lab2);
  	this.add(jtext2);
  	this.add(lab3);
  	this.add(jtext3);
  	this.add(lab4);
  	this.add(jtext4);
  	this.add(jb1);
  	this.add(jb2);  	
  	this.setLocationRelativeTo(null); 
  	this.setSize(200, 200); 
  	this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  	this.setResizable(false);
    this.setVisible(true); 
  }
  public void actionPerformed(ActionEvent e) {
  	if(e.getSource()==jb1) {
  		
  		if(jtext1.getText().length()==0||jtext2.getText().length()==0||jtext3.getText().length()==0||jtext4.getText().length()==0) 
  			JOptionPane.showMessageDialog(this, "請(qǐng)輸入完整數(shù)據(jù)!", "錯(cuò)誤", JOptionPane.INFORMATION_MESSAGE);
  		else {
  			mainclass.panel.lamp1.setgreentime(Integer.parseInt(jtext1.getText()));
  			mainclass.panel.lamp2.setgreentime(Integer.parseInt(jtext2.getText()));
  			mainclass.panel.lamp3.setgreentime(Integer.parseInt(jtext3.getText()));
  			mainclass.panel.lamp4.setgreentime(Integer.parseInt(jtext4.getText()));
  			this.dispose();
  		}
  	}else if(e.getSource()==jb2){
  		this.dispose();
  	}
  }
}

mainclass主類:

package traffic;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; 
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane; 
public class mainclass extends JFrame implements ActionListener{
	static Mypanel panel;	
	JMenuBar jmb;
	JMenu jm1, jm2;
	JMenuItem jmi1, jmi2,jmi3,jmi4;
	welcomepanel sp;	
	mainclass(){
		this.setTitle("traffic lamp");
		this.setSize(420,450);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		jmb=new JMenuBar();	
		jm1=new JMenu("控制");
		jm2=new JMenu("設(shè)置");	
		jmi1=new JMenuItem("開始模擬");
		jmi1.addActionListener(this);
		jmi2=new JMenuItem("退出模擬");
		jmi2.addActionListener(this);
		jmi3=new JMenuItem("隨機(jī)生成小車");
		jmi3.addActionListener(this);
		jmi4=new JMenuItem("更改綠燈時(shí)間");
		jmi4.addActionListener(this);
		jm1.add(jmi1);
		jm1.add(jmi2);
		jm1.add(jmi3);
		jm2.add(jmi4);
		jmb.add(jm1);
		jmb.add(jm2);
		
		this.setJMenuBar(jmb);
		
		sp=new welcomepanel();
		Thread t=new Thread(sp);
		t.start();
		this.setContentPane(sp);
		
		this.setLocationRelativeTo(null); 
		this.setResizable(false);
		this.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==jmi1) {
			sp.isLive=false;
			this.remove(sp);
			panel = new Mypanel();
			this.setContentPane(panel);
			this.setVisible(true);
		}else if(e.getSource()==jmi2) {
			System.exit(0);
		}else if(e.getSource()==jmi3) {
			if(panel==null)
  			JOptionPane.showMessageDialog(this, "請(qǐng)開始模擬再生成小車", "錯(cuò)誤", JOptionPane.INFORMATION_MESSAGE);
			else panel.addcar();
		}else if (e.getSource() == jmi4) {
			if(mainclass.panel==null)
  			JOptionPane.showMessageDialog(this, "請(qǐng)開始模擬再進(jìn)行設(shè)置", "錯(cuò)誤", JOptionPane.INFORMATION_MESSAGE);
			else new set();
			}
		}
	public static void main(String[] args) {
		new mainclass();
	}
}

多線程正確性測(cè)試:

我們?cè)趌amp類的run()方法中添加了一句控制臺(tái)打印命令,每次進(jìn)程運(yùn)行時(shí)即會(huì)打印此進(jìn)程的name成員

正確的打印結(jié)果應(yīng)該為 0-1-2-3-4-0-1-2-3-4-.......-1-2-3-....

控制臺(tái)的輸出結(jié)果為:

符合預(yù)測(cè)結(jié)果,實(shí)驗(yàn)完成!

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論