A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lwy0319 高级黑马   /  2014-4-3 04:40  /  1364 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 lwy0319 于 2014-4-3 04:43 编辑

试着根据交通灯系统先写一个路口车辆刷新的小样,但是计数器总是隔两个,求解
  1. import java.util.*;
  2. class Road{
  3.         public List<String> road=new ArrayList<String>();
  4. }
  5. class Addcar implements Runnable{
  6.         Road r;
  7.         Addcar(Road r){
  8.                 this.r=r;
  9.         }
  10.         public void run(){
  11.                 for(int i=1;i<100;i++){
  12.                         synchronized(r){
  13.                                 if(r.road.size()==0){
  14.                                         try {
  15.                                                 Thread.sleep(1000);
  16.                                         } catch (InterruptedException e) {
  17.                                                 e.printStackTrace();
  18.                                         }
  19.                                         r.road.add("car"+i);
  20.                                         System.out.println(r.road.get(0)+"驶入");
  21.                                 }else{
  22.                                         try {
  23.                                                 r.wait();
  24.                                         } catch (InterruptedException e) {
  25.                                                 e.printStackTrace();
  26.                                         }
  27.                                 }
  28.                                 r.notify();
  29.                         }
  30.                 }
  31.         }
  32. }
  33. class Removecar implements Runnable{
  34.         Road r;
  35.         Removecar(Road r){
  36.                 this.r=r;
  37.         }
  38.         public void run() {
  39.                 for(int i=1;i<100;i++){
  40.                         synchronized(r){
  41.                                 if(r.road.size()!=0){
  42.                                         try {
  43.                                                 Thread.sleep(1000);
  44.                                         } catch (InterruptedException e) {
  45.                                                 e.printStackTrace();
  46.                                         }
  47.                                         System.out.println(r.road.get(0)+"驶出");
  48.                                         r.road.remove(r.road.get(0));
  49.                                         }else{
  50.                                                 try {
  51.                                                         r.wait();
  52.                                                 } catch (InterruptedException e) {
  53.                                                         e.printStackTrace();
  54.                                                 }
  55.                                         }
  56.                                 r.notify();
  57.                                 }
  58.                         }
  59.                 }        
  60.         }
  61. public class ThreadDemo1 {
  62.         public static void main(String[] args){
  63.                 Road r=new Road();
  64.                 Addcar writer=new Addcar(r);
  65.                 Removecar reader=new Removecar(r);
  66.                 new Thread(writer).start();
  67.                 new Thread(reader).start();
  68.         }
  69. }
复制代码
是因为它每轮都要等待一次,但是这个时候i++了么?如果较真的话有没有办法优化这个问题?虽然如果不计数的话我的目的也算达到一部分了


评分

参与人数 1技术分 +1 收起 理由
zzkang0206 + 1

查看全部评分

2 个回复

倒序浏览
run方法中的for循环换成while循环,i++ 放在 r.road.add("car"+i);后面。类似下面的
  1. public void run(){
  2.         //for(int i=1;i<100;i++)
  3.         int i = 1;
  4.         while(i<100)
  5.         {
  6.             synchronized(r){
  7.                 if(r.road.size()==0){
  8.                     try {
  9.                         Thread.sleep(1000);
  10.                     } catch (InterruptedException e) {
  11.                         e.printStackTrace();
  12.                     }
  13.                     r.road.add("car"+i);
  14.                     i++;
  15.                     System.out.println(r.road.get(0)+"驶入");
  16.                 }
  17.                 else{
  18.                     try {
  19.                         r.wait();
  20.                        
  21.                     } catch (InterruptedException e) {
  22.                         e.printStackTrace();
  23.                     }
  24.                 }
  25.                 r.notify();
  26.             }
  27.             //System.out.println(i);
  28.         }
  29.     }
复制代码


分析一下你原来的程序:
假如执行过程如下:
第一步:执行addCar线程,此时i=1,执行完整个for循环一次后 ,i会自增一,这时不满足条件,会执行wait,addCar线程停止在这。
接着执行removeCar 取出一辆车,这时会notify,notify会唤醒addCar线程,(关键就在这 ,它会从addCar线程停止的地方继续执行,执行完后,for循环会又执行一次,这时i++后,i=3,然后在增加一辆车,这时车的编号就是3了,而不是2)

评分

参与人数 1黑马币 +3 收起 理由
lwy0319 + 3

查看全部评分

回复 使用道具 举报
林发明 发表于 2014-4-6 10:32
run方法中的for循环换成while循环,i++ 放在 r.road.add("car"+i);后面。类似下面的

原来如此,谢谢你,受教了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马