最近一直在优化海量数据(几千万)处理这一块。我使用的是java提供的ExecuterPool线程池来实现的,这几天在研究如何使用生产者和消费者模式去解决类似处理数据的问题,下面是思考与实现的过程~
思考
简单的介绍下生产者与消费者模式,详细的可以去google。
吃过快餐肯定会遇到这样的场景:
你去打土豆丝,拿着大勺的大妈就会往你的盘子里放上一勺土豆丝,后厨的师傅会时不时的把做好的土豆丝端上来,有时候你去晚了,然而土豆丝师傅还在做,你又很想吃,那就只能稍等一会了,有时候人很多,那么可能就会有两三个大妈负责盛菜。
好了,来分析下上面的场景,一些名词在下面的程序中有出现
- 生产者(Producer)负责生产数据即厨师抄土豆丝;
- 消费者(Ponsumer)负责处理数据即“你”吃土豆丝;
(这里可能要把“大妈就往你的盘子里放上一勺土豆丝”作为消费者的行为,具体需要个人去体会,这里只是方便理解) - 缓冲区(Storage)负责数据的缓存即大妈身旁的菜盘子;
好的,然后回到处理数据的问题上,我简单画了一下过程:
如果你有处理过数据,这个过程你肯定会遇到
- 黑色表示数据的流动:读数据->存到集合中->处理数据->存数据;
- 蓝色的表示各个环节的耗时操作
读数据时间、处理数据时间、存数据时间; - 红色表示的是需要优化的地方,大体包括软件(代码)与硬件(cpu个数与内存大小)。
生产者消费者的实现
下面是看了http://blog.chinaunix.net/uid-20680669-id-3602844.html博客 之后结合上图写出的代码。
Storage
public class Storage {
private List<String> cacheList; //工单数据列表
public boolean readOK;
/**
* 默认构造函数
*/
public Storage() {
cacheList = new ArrayList<>();
readOK = false;
}
/**
* 进行资源生产
*/
public synchronized void produce(List<String> listProducer) {
while (cacheList.size() != 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("increace error: " + e.getMessage());
}
}
if (listProducer.size() > 0) {
this.cacheList.addAll(listProducer);
} else {
readOK =