黑马程序员技术交流社区
标题:
空中网面试题!求解!
[打印本页]
作者:
创出一片辉煌
时间:
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
package read;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Test {
public static void main(String[] args){
final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(16);
for(int i = 0 ;i<4; i++ ){
new Thread(new Runnable(){
@Override
public void run() {
while(true){
try {
String log = queue.take();
Test.parseLog(log);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).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);//这行代码不能改动
{
// Test.parseLog(log);
try {
queue.put(log);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//parseLog方法内部的代码不能改动
public static void parseLog(String log){
System.out.println(log+":"+(System.currentTimeMillis()/1000));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
复制代码
作者:
杨健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