黑马程序员技术交流社区

标题: 空中网面试题!求解! [打印本页]

作者: 创出一片辉煌    时间: 2012-9-12 22:20
标题: 空中网面试题!求解!
/**
* 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,
* 请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,
* 程序只需要运行4秒即可打印完这些日志对象。
*/
public class InterviewDemo01 {

public static void main(String[] args){
  final BlockingQueue<String> bq = new ArrayBlockingQueue<String>(4);
  for(int i=0;i<4;i++){
    Thread th = new Thread(new Runnable(){
    public void run(){
     
     while(true){                   //为什么要加一个循环才能打印出十六条数据????   求解释???
      try {
       String str=bq.take();
       parseLog(str);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
     }
       System.out.println("33");   //为什么这段代码放在while后面编译不能通过,而放在while前面能通过???
    }
   },"ok-->"+i);
      th.start();
  }
        
  System.out.println("begin:"+(System.currentTimeMillis()/1000));
  /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
  修改程序代码,开四个线程让这16个对象在4秒钟打完。
  */
  for(int i=0;i<16;i++){  //这行代码不能改动
   final String log = ""+(i+1);//这行代码不能改动
   {
    try {
     bq.put(log);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
}

//parseLog方法内部的代码不能改动
public static void parseLog(String log){
  System.out.println(log+":"+Thread.currentThread().getName()+"       "+(System.currentTimeMillis()/1000));
  
  try {
   Thread.sleep(1000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }  
}

}

作者: 尤圣回    时间: 2012-9-13 15:45
  1. package read;

  2. import java.util.concurrent.ArrayBlockingQueue;
  3. import java.util.concurrent.BlockingQueue;

  4. public class Test {
  5.   
  6.   public static void main(String[] args){
  7.    final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
  8.          for(int i = 0 ;i<4; i++ ){
  9.           new Thread(new Runnable(){

  10.      @Override
  11.      public void run() {
  12.       while(true){
  13.        try {
  14.         String log = queue.take();
  15.         Test.parseLog(log);
  16.        } catch (InterruptedException e) {
  17.         // TODO Auto-generated catch block
  18.         e.printStackTrace();
  19.        }
  20.       }
  21.      }
  22.            
  23.           }).start();
  24.          }
  25.    System.out.println("begin:"+(System.currentTimeMillis()/1000));
  26.    /*模拟处理16行日志,下面的代码产生了16个日志对象,当前代码需要运行16秒才能打印完这些日志。
  27.    修改程序代码,开四个线程让这16个对象在4秒钟打完。
  28.    */
  29.    for(int i=0;i<16;i++){  //这行代码不能改动
  30.     final String log = ""+(i+1);//这行代码不能改动
  31.     {
  32. //          Test.parseLog(log);
  33.          try {
  34.        queue.put(log);
  35.       } catch (InterruptedException e) {
  36.        // TODO Auto-generated catch block
  37.        e.printStackTrace();
  38.       }
  39.     }
  40.    }
  41.   }
  42.   
  43.   //parseLog方法内部的代码不能改动
  44.   public static void parseLog(String log){
  45.    System.out.println(log+":"+(System.currentTimeMillis()/1000));
  46.    
  47.    try {
  48.     Thread.sleep(1000);
  49.    } catch (InterruptedException e) {
  50.     e.printStackTrace();
  51.    }  
  52.   }
  53.   
  54. }
复制代码

作者: 杨健yj    时间: 2012-9-13 20:35
/*

1 首先说下  System.out.println("33"); // 为什么这段代码放在while后面编译不能通过,而放在while前面能通过???

这是因为 while(true){};
                 System.out.println("33");
                 你的while循环不会结束,所以就不会执行改sys语句,类似于再break后面加语句。


2  为什么要加一个循环才能打印出十六条数据???? 求解释???
       
        因为 前面for语句开启了四个线程,每个线程在等待集合中数据的到来,当集合中有数据时,4个线程就互相抢,
        但是不知道要执行几次(理想状态每个线程执行4次)String str = bq.take();

最后说下,后面一下子往集合中加入16个数据,于是四个线程就开始争抢了,类似于张老师讲的银行调度系统,一个道理。

*/
作者: 杨震    时间: 2012-9-13 21:20
楼上正解
一,那个打印语句为什么不能放在后面,是因为while不会结束,eclipse上面有提示,Unreachable code,代码执行不到
二,为什么要循环:很显然如果没有循环,每个线程里面只在队列里取一次数据就结束了,四个线程只取四次数据,不符合要求,共有16个数据

这题重点我觉得是这个阻塞队列,它的put方法在队列满时会阻塞(take方法在队列为空时也会阻塞),开始for循环四次产生四个log放在队列里队列满for循环阻塞,然后等线程来抢数据
作者: 尤圣回    时间: 2012-9-13 21:21
尤圣回 发表于 2012-9-13 15:45

哦哦 问题没看清楚 等下在仔细看看 现在在看ejb没时间看你的题目




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2