设为首页 加入收藏

TOP

双缓冲队列的Java实现
2014-11-24 03:08:11 来源: 作者: 【 】 浏览:2
Tags:缓冲 队列 Java 实现

前段时间,做了个“双缓冲队列”,可是测试的效果就是不怎么明显,理论完全都在这里,可是就是看不到效果。
昨天在某某的提示下,终于意识到不该用阻塞队列,换成普通的List对象,这样效果就明显多啦~~
又重新写了一篇文档,如下提出问题:为啥要有双缓冲队列?



引用09年9月《程序员》上的一句话:双缓冲队列就是冲着同步/互斥的开销来的。我们知道,在多个线程并发访问同一个资源的时候,需要特别注意线程的同步问题。稍稍不注意,哦活,程序结果不正确了。最经典的就是“银行取钱”的例子,想想,都跟现金挂上钩了,看来这真不容忽视。


今天我们要谈的不是如何去给资源加锁解锁来解决同步问题,今天的重点在于,如何将线程同步的开销降低到我们力所能及的程度。如果你觉得,你可以通过增加硬件资源来弥补程序开销,那么,你将不可能成为一个优秀的程序员。
进入正题,先引入一个例子,两个实体:一个是玩具工厂,它的工作就是不停地生产玩具;另外一个实体就是小孩,它的工作就是不停地从工厂拿玩具。小孩不可能直接到工厂去“拿”玩具吧?呵呵,妈妈是绝对不会放心的。所以,我们有一个“搬运工”,搬运工自然要具备“存放”的功能,不然他怎么将玩具带给小孩呢,是吧。所以,我们先将搬运工定义为一个List,用来存放工厂生产出来的玩具。



玩具类,定义一个玩具实体
public class Toy {
private String name;


public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}



生产玩具的玩具工厂,相当于生产者
package twoBufferQueue;



public class Factory extends Thread {
public void run() {
while (true) {


Toy t = new Toy();


t.setName("玩具");
synchronized (Tools.lP) {
if (Tools.lP.size() >= 2000) {
try {
Tools.lP.wait();
} catch (Exception e) {
// TODO: handle exception
}
}
Tools.lP.add(t);
// System.out.println("put one");
}
}


}
}


小孩取玩具,相当于消费者


package twoBufferQueue;



public class Kid extends Thread {
long time1 = System.currentTimeMillis();
int count = 0;


public void run() {
while (true) {


synchronized (Tools.lT) {
if (Tools.lT.size() != 0){
Tools.lT.remove(0);
count++;
}

}

if (count == 100000) {
System.out.println("time:" + (System.currentTimeMillis() - time1));
System.exit(0);
}


}
}


}



双缓冲队列,里面有两个List


package twoBufferQueue;


import java.util.List;


public class DoubleBufferList {
private List lP;
private List lT;
private int gap;



public DoubleBufferList(List lP, List 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.notifyAll();
}
lP.clear();

}
}
}
}
};
Thread thread = new Thread(runner);
thread.start();
}


}



运行的主线程类:


package twoBufferQueue;


public class MainTest {
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();
}
}


运行结果:time:265毫秒 确实很快,比用一个List的生产者消费者模型快很多,不至几倍...强烈建议大家使用。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Java 关于异常处理 下一篇如何用C++产生随机数

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·switch520最新的地址 (2025-12-24 19:19:41)
·微信聊天功能使用了 (2025-12-24 19:19:39)
·websocket和普通的so (2025-12-24 19:19:36)
·Python中文网 - 人生 (2025-12-24 18:49:47)
·【整整648集】这绝对 (2025-12-24 18:49:44)