锁定老帖子 主题:双缓冲队列尝试
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-16
最后修改:2009-09-16
提出背景: 首先我们来看看不使用双缓冲机制的程序: package cn.netjava.lbq.copy;
//玩具类 public class Toy { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } package cn.netjava.lbq.copy;
//在线程中生产玩具,放入单缓冲队列 public class Factory extends Thread{ public void run(){ while(true){ Toy t = new Toy (); t.setName("玩具"); try { Tools.lT.put(t); System.out.println("生产出一个玩具"); } catch (InterruptedException e) { e.printStackTrace(); } } } } package cn.netjava.lbq.copy; //从单缓冲队列中取出玩具对象 public class Kid extends Thread { long time1 = System.currentTimeMillis(); int count = 0; public void run() { while(true){ try { Tools.lT.take(); count++; //计算取100000个所需要的时间 if(count==100000){ System.out.println(System.currentTimeMillis()-time1); Thread.sleep(100000); } System.out.println("玩完一个玩具"); } catch (InterruptedException e) { e.printStackTrace(); } } } } package cn.netjava.lbq.copy; //存放玩具对象的的队列 import java.util.concurrent.LinkedBlockingQueue; public class Tools { public static LinkedBlockingQueue<Tool>lT = new LinkedBlockingQueue<Tool>(10000); } package cn.netjava.lbq.copy; public class MainTest { /** * @param args */ public static void main(String[] args) { Factory f = new Factory(); f.start(); Kid k = new Kid(); k.start(); } } 取出100000个玩具的时间为:3609ms
再来看看使用双缓冲队列的情况,toy类就不再贴出了。 看其他类,中间做了一些改动 package cn.netjava.lbq; import java.util.concurrent.LinkedBlockingQueue; public class Tools { public static LinkedBlockingQueue<Tool>lT = new LinkedBlockingQueue<Tool>(10000); public static LinkedBlockingQueue<Tool>lP = new LinkedBlockingQueue<Tool>(10000); } package cn.netjava.lbq; public class Kid extends Thread { long time1 = System.currentTimeMillis(); int count = 0; public void run() { while(true){ try { Tools.lT.take(); count++; if(count==10000){ System.out.println(System.currentTimeMillis()-time1); Thread.sleep(100000); } System.out.println("玩完一个玩具"); } catch (InterruptedException e) { e.printStackTrace(); } } } } package cn.netjava.lbq; import java.util.concurrent.LinkedBlockingQueue; public class Factory extends Thread{ public void run(){ while(true){ Toy t = new Toy (); t.setName("玩具"); try { Tools.lP.put(t); System.out.println("生产出一个玩具"); } catch (InterruptedException e) { e.printStackTrace(); } } } } package cn.netjava.lbq; import java.util.concurrent.LinkedBlockingQueue; /** * 定义一个双缓冲队列 * @author Irving * @time 2009-9-16----上午10:25:49 * */ public class DoubleBufferList { private LinkedBlockingQueue<Object> lP; private LinkedBlockingQueue<Object> lT; private int gap; /** * 构造方法 * @param lP 用来存放对象的阻塞队列 * @param lT 用来取对象的阻塞队列 * @param gap 交换的间隔 */ public DoubleBufferList(LinkedBlockingQueue lP ,LinkedBlockingQueue lT,int gap){ this.lP=lP; this.lT=lT; this.gap=gap; } public void check(){ Runnable runner = new Runnable(){ public void run() { while(true){ if(lT.size()==0){ synchronized(lT){ synchronized(lP){ lT.addAll(lP); } lP.clear(); } } try { Thread.sleep(gap); } catch (InterruptedException e) { e.printStackTrace(); } } } }; Thread thread = new Thread(runner); thread.start(); } } package cn.netjava.lbq; public class MainTest { /** * @param args */ public static void main(String[] args) { Factory f = new Factory(); f.start(); Kid k = new Kid(); k.start(); new DoubleBufferList(Tools.lP,Tools.lT,1).check(); } } 同样100000个玩具对象,使用的时间是3469ms,大约节约了200ms
在使用双缓冲队列的时候,要注意调试监测线程的监控时间间隔和阻塞队列的大小,这些都是影响运行速度的关键因素。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-09-16
本人有两个问题:
1.博主提出的性能问题是不是由于lT.take(),lT.put()都作用于同一个对象造成的? 2.对于 if(lT.size()==0){ lT.addAll(lP); lP.clear(); } 当程序已经执行了lT.addAll(lP)还未执行lP.clear(),这时候如果lP.put(t)又放进了一个对象,那么这个对象不就会被清理掉了? |
|
返回顶楼 | |
发表时间:2009-09-16
最后修改:2009-09-16
sahero 写道 本人有两个问题:
1.博主提出的性能问题是不是由于lT.take(),lT.put()都作用于同一个对象造成的? 2.对于 if(lT.size()==0){ lT.addAll(lP); lP.clear(); } 当程序已经执行了lT.addAll(lP)还未执行lP.clear(),这时候如果lP.put(t)又放进了一个对象,那么这个对象不就会被清理掉了? 呵呵,第一点,我个人觉得性能问题是由于lT.take(),lT.put()都作用于同一个对象造成的。 第二点,程序应该这样改下才合适 if(lT.size()==0){ synchronized(lT){ synchronized(lP){ lT.addAll(lP); } lP.clear(); } } 谢谢提醒啊。我现在正在做一个关于CMPP的模拟程序,关于改善线程同步来提高性能方面也在考虑当中,希望有机会可以和你讨论讨论啊。 |
|
返回顶楼 | |
浏览 3029 次