黑马程序员技术交流社区
标题: 一个用枚举构造的模拟交通灯,运行终止 [打印本页]
作者: 云惟桉 时间: 2012-5-3 00:05
标题: 一个用枚举构造的模拟交通灯,运行终止
- package cn.itcast.day1;
- public class EnumTest {
- public static void main(String[] args){
- new Thread(new Runnable(){
- public void run(){
- display(TrafficLamp.RED);
- }
- }).start();
- new Thread(new Runnable(){
- public void run(){
- display(TrafficLamp.GREEN);
- }
- }).start();
- }
- public enum TrafficLamp{
- //当抽象方法存在,必须覆盖枚举类中的抽象方法
- RED(25){
- public TrafficLamp nextLamp(){
- return GREEN;
- }
- },GREEN(20){
- public TrafficLamp nextLamp(){
- return YELLOW;
- }
- },YELLOW(5){
- public TrafficLamp nextLamp(){
- return RED;
- }
- };
- public abstract TrafficLamp nextLamp();
- private int time;
- private TrafficLamp(int time){
- this.time = time;
- }
- public int getTime(){
- return time;
- }
- public void setTime(int time){
- this.time = time;
- }
- }
- public static void display(TrafficLamp state){
- while (true) {
- switch (state) {
- case GREEN:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- }
- case RED:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- }
- case YELLOW:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- }
- }
- }
- }
- public static int lampSleep(TrafficLamp state,int count){
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(state.toString()+count);
- count--;
- return count;
- }
- }
复制代码 有没有人可以用eclipse运行一下以上代码,代码的目标是:
运行一个模拟交通灯,进行倒计时,红-->黄-->绿-->红,每秒都会输出“灯状态+剩余秒数”。
我遇到的问题是:
当交通灯走完一个循环以后,似乎阻塞住不动了,但是主线程还在运行中,因为运行并没有终止,这是怎么回事呢?
为了验证是不是主线程问题,我还自己在main中加了两个线程来运行,貌似仍然会出现同样的问题,
求帮助,求解答
作者: 贾联国 时间: 2012-5-3 00:41
本帖最后由 贾联国 于 2012-5-3 00:44 编辑
- 我觉得楼主的代码适合写成单线程,因为有state.nextLamp();,直接单线程互相转换就行。我运行了单线程,很正常~!
主函数直接用:
public static void main(String[] args){
new Thread(new Runnable(){
public void run(){
display(TrafficLamp.RED);
}
}).start();
楼主写的代码非常好哇~!
不用state.nextLamp();的话可以用3线程的相互唤醒,不过不如楼主的简单~
作者: 云惟桉 时间: 2012-5-3 01:04
贾联国 发表于 2012-5-3 00:41
我觉得楼主的代码适合写成单线程,因为有state.nextLamp();,直接单线程互相转换就行。我运行了单线程 ...
谢谢夸奖,本人新人一枚。
嗯,其实用单线程的话就和用main直接执行应该是一样的。
我用两个线程是假设模拟东西方向 和 南北方向的灯转换。严谨一些应该加个同步什么的。为了单纯演示我就偷懒了。
我试了一下,其实按理来说是只要不手动停止程序的话,是会一直循环打印的。但是我尝试了一次还是不行。比如打印 red--->green-->yellow 然后就停止打印了,但是Main函数还是在运行的。
所以,不知道是我eclipse的问题,还是其他。
不过还是感谢帮忙,因为帖子没什么人回。
估计黑马9期招满了以后,论坛的活跃性就稍微减弱了吧。
作者: 贾联国 时间: 2012-5-3 01:37
云惟桉 发表于 2012-5-3 01:04 
谢谢夸奖,本人新人一枚。
嗯,其实用单线程的话就和用main直接执行应该是一样的。
南北走向也是可以的,我的eclipse也是同样问题,但是控制台就没有问题。
作者: 刘少伟 时间: 2012-5-3 02:20
lz你的nextLamp实现貌似不是红-黄-绿-红的顺序 把返回值改一下吧、
另外就是switch/case的地方,每一段之后就要break,否则每次循环三个case都执行,相当于,循环一次,同一个灯的time减减三次(time大于0的时候),比如起步是红灯,第一次循环之后,红灯的time减了3,其他灯没变。
还有就是,在切换下一个灯之后,把下一个灯的时间重置,三个灯都走完一次不动就是因为他们的时间都归零了。这样我用单线程走了一次看起来是正常的。你自己再看一下吧,很晚了 先睡了明天还要上班{:soso_e136:}
作者: 云惟桉 时间: 2012-5-3 13:21
刘少伟 发表于 2012-5-3 02:20 
lz你的nextLamp实现貌似不是红-黄-绿-红的顺序 把返回值改一下吧、
另外就是switch/case的地方,每一段之后 ...
十分感谢帮忙!但是灯的状态是没错的,绿灯之后才是黄灯,生活里的顺序。
另外,我查阅了一下java核心技术,才发现我的错,原文是这样的:
【警告】:switch语句有可能触发多个case分支。如果在case分支语句的末尾没有break语句,那么就会接着执行下一个case分支语句。这种情况相当危险,常常会引发错误。为此,我们在程序中从不使用switch语句。
——P70 《Java核心技术:卷1:基础知识》
细节真的使人挫败啊,楼主真是有心人。正确的解决方法就像你所说的,应该是考虑两点:
1.运行过程使用set方法修改了time的值,因此在状态转换时一定需要重置time;
2.没有break语句,无论满不满足case判断,每一个case都会执行(可以使用system.out输出检验)
希望我的错误能给看帖的人带来收获。
正确代码如下:
- public static void display(TrafficLamp state){
- while (true) {
- switch (state) {
- case GREEN:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- state.setTime(5);
- }
- break;
- case RED:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- state.setTime(20);
- }
- break;
- case YELLOW:
- if (state.getTime() != 0) {
- state.setTime(lampSleep(state, state.getTime()));
- } else {
- state = state.nextLamp();
- state.setTime(25);
- }
- break;
- }
- }
- }
复制代码
作者: 云惟桉 时间: 2012-5-3 13:24
贾联国 发表于 2012-5-3 01:37 
南北走向也是可以的,我的eclipse也是同样问题,但是控制台就没有问题。
...
经过有心人提点,终于找到错误了。
你可以看我的回复,希望你也有收获,呵呵。
作者: 飞舞❤心动 时间: 2012-6-12 09:09
收获很大!
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |