【Java多线程与并发库】18.java线程面试题1
来源:互联网 发布:头像psd源码 编辑:程序博客网 时间:2024/06/06 19:43
现有的程序代码模拟产生了16个日志对象,并且需要运行16秒才能打印完这些日志,请在程序
中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印
玩这些日志对象。原始代码如下:
演示:
我们下面来改造这段代码,使得只需四秒就打印完。
这是我自己写的答案:
我创建了容量为4的线程池,然后每次打印的时候创建一个新的线程对象放进去,因为
容量为4,每次只有四个线程同时运行,所以每一秒钟完成四个,下四个线程进去继续运行,如此就实现了4秒打印16个日志的效果。
官方给的是使用阻塞队列来完成,其实同样,这个问题也可以这么解决:
总结一下,我个人认为官方的答案虽然也实现了这个效果,但是我认为有以下缺陷:
1.线程中有死循环,将会一直占用CPU的内存,这种做法不是很好。
2.线程打印出来的日志文件的顺序是乱序,在尚不知晓日志打印顺序对其它业务有何影响
的情况下,这种做法也不是很好。
3.代码量大,相比我使用线程池的做法,使用阻塞队列的代码量明显要大于我的代码量。
转载请注明出处:http://blog.csdn.net/acmman/article/details/53116117
中增加4个线程去调用parseLog()方法来分头打印这16个日志对象,程序只需要运行4秒即可打印
玩这些日志对象。原始代码如下:
package cn.edu.hpu.test;public class ReadTest { public static void main(String[] args) { System.out.println("begin:"+(System.currentTimeMillis()/1000)); /*模拟处理16行日志,下面的代码产生了16条日志对象, * 当前代码需要运行16秒才能打印完这些日志*/ for (int i = 0; i < 16; i++) { final String log = ""+(i+1);//这行代码不能改动 { ReadTest.parseLog(log); } } } //parseLog方法内的代码不能改动 private static void parseLog(String log) { System.out.println(log+":"+(System.currentTimeMillis()/1000)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }}其实就是生成一条花一秒,然后再去生成下个日志。
演示:
我们下面来改造这段代码,使得只需四秒就打印完。
这是我自己写的答案:
package cn.edu.hpu.test;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class ReadTest { public static void main(String[] args) { ExecutorService executor=Executors.newFixedThreadPool(4);//创建容量为4的线程池 System.out.println("begin:"+(System.currentTimeMillis()/1000)); /*模拟处理16行日志,下面的代码产生了16条日志对象, * 当前代码需要运行16秒才能打印完这些日志*/ for (int i = 0; i < 16; i++) { final String log = ""+(i+1);//这行代码不能改动 { executor.execute(new Runnable(){//每打印一次日志执行一个线程 public void run() { ReadTest.parseLog(log); } }); } } } //parseLog方法内的代码不能改动 private static void parseLog(String log) { System.out.println(log+":"+(System.currentTimeMillis()/1000)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }结果:
我创建了容量为4的线程池,然后每次打印的时候创建一个新的线程对象放进去,因为
容量为4,每次只有四个线程同时运行,所以每一秒钟完成四个,下四个线程进去继续运行,如此就实现了4秒打印16个日志的效果。
官方给的是使用阻塞队列来完成,其实同样,这个问题也可以这么解决:
package cn.edu.hpu.test;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class ReadTest { public static void main(String[] args) { final BlockingQueue<String> queue=new ArrayBlockingQueue<String>(4);//创建容量为4的阻塞队列 for (int i = 0; i < 4; i++) { new Thread(new Runnable(){ //该线程等待打印,只要queue有数据,就立马开始打印 public void run() { String log=null; while(true){ try { if(queue.size()>0){ log=queue.take(); ReadTest.parseLog(log); } } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } System.out.println("begin:"+(System.currentTimeMillis()/1000)); /*模拟处理16行日志,下面的代码产生了16条日志对象, * 当前代码需要运行16秒才能打印完这些日志*/ for (int i = 0; i < 16; i++) { final String log = ""+(i+1);//这行代码不能改动 { try { queue.put(log); } catch (InterruptedException e) { e.printStackTrace(); } } } } //parseLog方法内的代码不能改动 private static void parseLog(String log) { System.out.println(log+":"+(System.currentTimeMillis()/1000)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }效果:
总结一下,我个人认为官方的答案虽然也实现了这个效果,但是我认为有以下缺陷:
1.线程中有死循环,将会一直占用CPU的内存,这种做法不是很好。
2.线程打印出来的日志文件的顺序是乱序,在尚不知晓日志打印顺序对其它业务有何影响
的情况下,这种做法也不是很好。
3.代码量大,相比我使用线程池的做法,使用阻塞队列的代码量明显要大于我的代码量。
转载请注明出处:http://blog.csdn.net/acmman/article/details/53116117
0 0
- 【Java多线程与并发库】18.java线程面试题1
- 【Java多线程与并发库】19.java线程面试题2
- 【Java多线程与并发库】20.java线程面试题3
- 转载-java多线程与并发面试题
- java面试题_并发与多线程
- Java 多线程 并发 锁 Java线程面试题 Top 50
- java多线程,并发面试题
- Java面试题--多线程、并发及线程的基础问题
- JAVA多线程和并发基础面试题
- JAVA多线程和并发基础面试题
- java并发多线程面试题和答案
- Java并发多线程面试题 Top 50
- Java并发多线程面试题 Top 50
- JAVA多线程和并发基础面试题
- Java多线程高并发基础面试题
- Java并发多线程面试题 Top 50
- JAVA多线程和并发基础面试题
- java多线程和并发基础面试题
- 字符串的逆序输出和在大串中查找小串出现的次数
- BAT编程
- 行业巨头力挺支持H5人才需求急扩张
- js中return、return true、return false
- 40. Combination Sum II
- 【Java多线程与并发库】18.java线程面试题1
- 关于jdbc的数据库驱动类DriverManager.getConnection()参数
- POJ 1426Find The Multiple(DFS)
- this指针
- 循环小数的循环节问题
- JQ实现多二级联动菜单的实现
- 微信六大接收接口(接收普通消息)
- RemoteCallbackList的使用
- ucos-ii学习笔记——消息队列的原理及使用