-------
android培训、
java培训、期待与您交流! ----------
public class Skytest1 {
/**
* 第一题:现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,
* 请在程序中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运
* 行4秒即可打印完这些日志对象
*/
public static void main(String[] args){
//我们先创建一个固定大小为16的队列。主线程一次性将16个数据添加到队列中
//子线程4个,分批去拿的,每批所有的子线程去拿的数据都是相同的。这里共批次去拿数据
//1批中第一个子线程执行完之后,第二个子线程执行。...依次类推
//这里是一次把数据全部存完。然后每次4个子线程去取。一次只能有一个子线程执行。即
//阻塞队列有互斥和同步通知的功能。
final BlockingQueue<String> queue=new ArrayBlockingQueue<String>(16);
//现在我们来使用大小为1的队列来进行操作
//主线程添加一个数据到队列中之后。因为有4个线程要取数据。当一个线程取数据时。其它的线程
//处于阻塞状态。然后主线程又接着添加,然后处于阻塞中的一个线程取数据。这样循环下去。
//这里是存一个取一个
// final BlockingQueue<String> queue=new ArrayBlockingQueue<String>(1);
//我们要创建4个子线程就不能在原有的基础上创建。因为原来是一个循环。我们在里面
//创建了4个子线程外面还有16个了,这样线程的数量就达到64个了
//我们只能在外面创建子线程
for(int i=0;i<4;i++){
new Thread(new Runnable(){
public void run(){
while(true){
//我们在这里调用方法,但是子线程的数据该如何获取了
//应该有一个地方存储数据。但是又要实现主线程存数据的时候子线程不能取
//所以我们可以使用阻塞队列的方式来进行操作
try {
String log=queue.take();
Skytest1.parseLog(log); //调用静态方法最好写完整的格式:类名.方法名
} catch (InterruptedException e) {
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);//这行代码不能改动
{
// Skytest1.parseLog(log);
//既然是使用4个线程分别调用parseLog方法。我们在这里就不能调用这个方法
//在生成数据之后将生成的数据添加到阻塞队列中
try {
queue.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();
}
}
}