怎么看待java多线程交通信号灯模拟过程,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
成都创新互联公司专业为企业提供牧野网站建设、牧野做网站、牧野网站设计、牧野网站制作等企业网站建设、网页设计与制作、牧野企业网站模板建站服务,10余年牧野做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
交通信号灯的线程设计
实验目的:多线程设计,同步机制 题意 设计一个交通信号灯类: 变量:位置、颜色(红、黄、绿)、显示时间(秒)。 方法:切换信号灯。 创建并启动两个线程(东西向、南北向)同时运行。 实验要求 设计线程。 设计路口信号灯示意图界面。 进一步将每个方向的信号灯分成3种车道灯:左转、直行和右转。 根据车流量进行时间的模糊控制。
在课程设计的开始并没有仔细看老师的要求,只知道是交通信号灯。然后就开始各种找资料,百度,网上大量的关于红绿灯的设计都是参考张孝祥老师的教程,大概的设计方法是创建了三个类 lamp、road、lampcontrol。
然鹅......对.....然鹅又来了,在查了大概两天资料后,我又反过来看了一遍老师发的设计要求.....这这这.....,光控制灯就行了啊,不要车的啊,捂脸...
所以设计思路马上就变得清晰,根据张老师的做法,每个路口都有三个灯,分别为左转、直行、右转,所以一共有12盏灯。按照要求,右转灯为常亮灯,左转和直行灯才有红绿交替。在除去右转灯的八个灯里面,又可以分为四组可以两两匹配的灯,分别为东西左转南北(平行转垂直)、南北直行(垂直通行)、南北左转东西(垂直转平行)、东西直行(平行通行)。
于是我给这个12个灯编了个号:
emmm 大概就是这样,但是跟生活中的红绿灯不同,生活中的都是看对面路口的灯,我们这里是模拟嘛....就各个路口用各个路口的灯呗.....
大致解释一下,
1号灯为由南向西的左转灯,2号灯为由南向北的直行灯,3号灯为由南向东的右转灯。
4号灯为由东向北的右转灯,5号灯为由东向西的直行灯,6号灯为由东向南的左转灯。
7号灯为由北向西的右转灯,8号灯为由北向南的直行灯,9号灯为由北向东的左转灯。
10号灯为由西向北的左转灯,11号灯为由西向东的直行灯,12号灯为由西向南的右转灯。
然后根据匹配的原则,大概就是这么一张图:
我们就可以得到:
这四组信号灯。
到这里我们思路就很清晰了,我们可以分别为每一组信号灯开一个进程,然后使四个进程循环交替进行就实现了绿灯的转换。使用了程的同步技术。
当然,我们都已经开了四个进程了,为了锦上添花,我当然不介意再加个小车了hhhhhh
实验结果图:
源代码:
light类:
package traffic; public class light {int x,y; //灯在画布上的位置boolean status; //灯的状态public light(int x,int y,boolean islight) {this.x=x; this.y=y;this.status=islight;}public void setlight(boolean sta) { //对外接口更改灯的状态this.status=sta;}}
lamp类:
package traffic; public class lamp implements Runnable {light opposite, now; //相互匹配的两个灯int greentime; //绿灯亮的时间int name; //编组boolean status; //状态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实现进程间的互斥if (name == mainclass.panel.islight) { //使用辅助变量实现进程按顺序循环//System.out.println("now is: "+name);change();mainclass.panel.repaint();try {Thread.sleep(greentime);} catch (InterruptedException e) {e.printStackTrace();}lock.notifyAll(); //唤醒其他进程change();mainclass.panel.LampChange();mainclass.panel.repaint();try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}} else {try {lock.wait(); //挂起进程} 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; //十二个灯lamp lamp1,lamp2,lamp3,lamp4; //四组信号灯static int islight; //实现进程循环的辅助变量Random r=new Random();static public ArrayList 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 stubwhile (true) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 { //设置界面 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("南北左转东西:"); lab2=new JLabel("东西直行:"); lab3=new JLabel("东西左转南北:"); 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, "请输入完整数据!", "错误", 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("设置");jmi1=new JMenuItem("开始模拟");jmi1.addActionListener(this);jmi2=new JMenuItem("退出模拟");jmi2.addActionListener(this);jmi3=new JMenuItem("随机生成小车");jmi3.addActionListener(this);jmi4=new JMenuItem("更改绿灯时间");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, "请开始模拟再生成小车", "错误", JOptionPane.INFORMATION_MESSAGE);else panel.addcar();}else if (e.getSource() == jmi4) {if(mainclass.panel==null) JOptionPane.showMessageDialog(this, "请开始模拟再进行设置", "错误", JOptionPane.INFORMATION_MESSAGE);else new set();}}public static void main(String[] args) {new mainclass();}} 多线程正确性测试: 我们在lamp类的run()方法中添加了一句控制台打印命令,每次进程运行时即会打印此进程的name成员 正确的打印结果应该为 0-1-2-3-4-0-1-2-3-4-.......-1-2-3-.... 控制台的输出结果为: 符合预测结果,实验完成! 看完上述内容,你们掌握怎么看待java多线程交通信号灯模拟过程的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
文章标题:怎么看待java多线程交通信号灯模拟过程
分享地址:http://kswsj.cn/article/ppchsp.html