一、 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印完这些日志对象。原始代码如下
public class aa {
public static void main(String[] args) {
System.out.println("begin:" + (System.currentTimeMillis() / 1000));
for (int i = 0; i < 16; i++) { // 这行代码不能改动
final String log = "" + (i + 1);// 这行代码不能改动
{
Test.parseLog(log);
}
}
}
// parseLog方法内部的代码不能改动
public static void parseLog(String log) {
System.out.println(log + ":" + (System.currentTimeMillis() / 1000));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
改进后的代码:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Test {
public static void main(String[] args) {
//BlockingQueue为阻塞队列,队列拿走了只能拿其他的数据
final BlockingQueue<String> queue1 = new ArrayBlockingQueue<String>(16);
for (int i = 0; i < 4; i++) {
new Thread(new Runnable(){
public void run() {
while(true){
try {
String log = queue1.take();
parseLog(log);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
System.out.println("begin:" + (System.currentTimeMillis() / 1000));
for (int i = 0; i < 16; i++) { // 这行代码不能改动
final String log = "" + (i + 1);// 这行代码不能改动
{
//Test.parseLog(log);
try {
queue1.put(log);
} catch (InterruptedException e) {
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();
}
}
}
结果:
begin:1491222032
1:1491222032
2:1491222032
3:1491222032
4:1491222032
5:1491222033
8:1491222033
7:1491222033
6:1491222033
9:1491222034
11:1491222034
10:1491222034
12:1491222034
13:1491222035
15:1491222035
16:1491222035
14:1491222035