【天天动听】一道面试题分享.
2014-03-10 21:42
127 查看
最近去天天动听面试,出了以下编程题目.
大概是这样的.
一个生产者进程,一个消费者进程,生产者不断生产产品,消费者不断消费产品,产品量为N.
要求设计这两个进程使其满足如下要求.
1,生产顺序按照队列的方式,先进先出.
2,生产和消费可以同时进行
3 ,当生产容量满了后,不能继续生产,消费完了后不能继续消费
4,当生产容量满了或者消费完了,要节约CPU开销(不能使用sleep())
5,尽量少定义变量,高效率实现.
分析:(声明一下,可能下面内容有不对的地方,望各位指教)
这是一道线程间的同步和互斥问题.下面来对5个小求做下分析:
要求1生产顺序按照队列的方式,先进先出.这个要求其实不难实现,产品先放入第一个位置,然后当第二个产品生产出来后要把之前的第一个产品放到第二个位置上面去,刚才生产出来的产品放在第一个位置上,之后依次类推.
要求2生产和消费可以同时进行,这是考多线程.
要求3当生产容量满了后,不能继续生产,消费完了后不能继续消费.这个就是涉及到线程间的同步了.
要求4,当生产容量满了或者消费完了,要节约CPU开销(不能使用sleep()),这个是对要求3作了更进一步的要求,要求使用java中wait让线程挂起,不消耗cpu.
要求5,尽量少定义变量,高效率实现.这个应该是使答案产生亮点的地方
好了5个要求的分析完了下面来看看这道题实现.
这张图作为参考.
![](http://img.blog.csdn.net/20140310215850109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbWljYWl4aWFvZHVhbmt1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
首先是生产线程的实现:
然后是消费线程的实现
最后我写了个环境类,主要是用于公用变量的创建和线程的启动
最后说明一点:在实现过程中,我并没有去写产品的生产过程相关的代码,因为我觉得这并不是这道题的精髓(我们通过index去判断现在生产的产品数量.)
大概是这样的.
一个生产者进程,一个消费者进程,生产者不断生产产品,消费者不断消费产品,产品量为N.
要求设计这两个进程使其满足如下要求.
1,生产顺序按照队列的方式,先进先出.
2,生产和消费可以同时进行
3 ,当生产容量满了后,不能继续生产,消费完了后不能继续消费
4,当生产容量满了或者消费完了,要节约CPU开销(不能使用sleep())
5,尽量少定义变量,高效率实现.
分析:(声明一下,可能下面内容有不对的地方,望各位指教)
这是一道线程间的同步和互斥问题.下面来对5个小求做下分析:
要求1生产顺序按照队列的方式,先进先出.这个要求其实不难实现,产品先放入第一个位置,然后当第二个产品生产出来后要把之前的第一个产品放到第二个位置上面去,刚才生产出来的产品放在第一个位置上,之后依次类推.
要求2生产和消费可以同时进行,这是考多线程.
要求3当生产容量满了后,不能继续生产,消费完了后不能继续消费.这个就是涉及到线程间的同步了.
要求4,当生产容量满了或者消费完了,要节约CPU开销(不能使用sleep()),这个是对要求3作了更进一步的要求,要求使用java中wait让线程挂起,不消耗cpu.
要求5,尽量少定义变量,高效率实现.这个应该是使答案产生亮点的地方
好了5个要求的分析完了下面来看看这道题实现.
这张图作为参考.
首先是生产线程的实现:
/* * 生产线程类 */ public class Producer { private Thread produceThread = new Thread(){ @Override public void run() { // TODO Auto-generated method stub super.run(); while(true){ synchronized (Eviroment.obj) { //为了线程间互斥进行,防止同时操作index if(Eviroment.index < Eviroment.N){ try { sleep(200); //这不是题目中要求的不能用的sleep(),仅仅是为了方便观察结果(因为生产一个产品和消费一个产品时间不同的话,输出结果会更明显) } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //moving index Eviroment.index++; System.out.println("produce new product numbur: "+ Eviroment.index); Eviroment.obj.notify(); //当生产出一件产品后通知消费线程可以消费了.(当然这是在消费者线程消费完产品,处于wait状态才有效) } if(Eviroment.index == Eviroment.N -1){ //生产的产品已装满仓库 try { System.out.println("produceThread wait"); Eviroment.obj.wait(); //挂起线程 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }; public void startProduceThread(){ produceThread.start(); } }
然后是消费线程的实现
/* * 消费线程类 */ public class Consumer { private Thread ConsumerThread = new Thread(){ @Override public void run() { // TODO Auto-generated method stub super.run(); while(true){ synchronized (Eviroment.obj) { //为了线程间互斥进行,防止同时操作index if(Eviroment.index >= 0){ try { sleep(500); //这不是题目中要求的不能用的sleep(),仅仅是为了方便观察结果(因为生产一个产品和消费一个产品时间不同的话,输出结果会更明显) } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("consume product numbur: "+ Eviroment.index); //moving index Eviroment.index--; Eviroment.obj.notify(); //当消费一件产品后,说明仓库有空余位置了,通知消费线程可以生产了. } if(Eviroment.index == -1){ try { System.out.println("ConsumerThread wait"); Eviroment.obj.wait(); //消费者线程挂起 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } }; public void startConsumeProduct(){ ConsumerThread.start(); } }
最后我写了个环境类,主要是用于公用变量的创建和线程的启动
/* * 这是生产环境,主要是放些生产线程和消费线程同时用到的变量, * 我们的主线程就在这个类中去启动,然后分别启动生产线程和消费线程 */ public class Eviroment { public static Object obj = new Object(); //互斥对象 public static int index = -1; //index表示当前有产品的位置 public static int N = 10; //N代表仓库最大容量 public static void main(String [] args){ Producer pro = new Producer(); Consumer con = new Consumer(); pro.startProduceThread(); //开始生产线程 con.startConsumeProduct(); //开始消费线程 } }
最后说明一点:在实现过程中,我并没有去写产品的生产过程相关的代码,因为我觉得这并不是这道题的精髓(我们通过index去判断现在生产的产品数量.)
相关文章推荐
- 分享:一道面试题
- 分享一道JS前端闭包面试题
- 一道淘宝的面试题,记录分享下~
- 收集了一道面试题(字符串翻转),有答案,拿出来和大家分享。
- 看到的一道面试题,很有趣,与大家分享zt
- 分享我的一道电商需求分析的面试题!
- 分享一道关于闭包、bind和this的面试题
- 分享一道面试题
- 一道淘汰85%面试者的百度开发者面试题参考答案
- 一道阿里巴巴的面试题解答
- 一道面试题
- 一道看上去很吓人的算法面试题:如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
- 关于正则表达式的一道面试题
- JavaScript一道面试题求y的值是? z 的值是? s的值是?
- 线程:一道线程的面试题
- 一道简单的面试题
- 由一道Java面试题想到的(关于类初始化以及多态)(一)
- 一道前端面试题:用原生JS实现,点击按钮,alert-button的内容
- 统计回文--一道面试题的反思
- 一道沙漏面试题