词频统计程序
主循环的每一次循环都完成了两个任务——首先解析XML并构造一个Page,然后“消费”这个page,对page中的内容统计词频。
这类问题可以归结为一种经典模式——生产者-消费者(producer-consumer)模式。
生
词频统计程序—生成者消费者模式
定义生产者Parser:
定义消费者:
创建两个线程:
并
ArrayBlockingQueue并发队列
非常适合实现生产者-消费者模式。
其提供了高效的并发方法put()和take(),这些方法会在必要时阻塞:当对一个空队列调用take()时,程序会阻塞直到队列变为非空;当对一个满队列调用put()时,程序会阻塞直到队列有足够空间。
VS
ConcurrentLinkedQueue
VS ArrayBlockingQueue
容量无限、操作不需等待、非阻塞的队列ConcurrentLinkedQueue。
关键在于生产者和消费者可能不会(几乎肯定不会)保持相同的速度。
相比之下,阻塞队列只允许生产者的速度在一定程度上超过消费者的速度,但不会超过很多。
毒
毒丸
消费者如何知道何时应该退出:
毒丸(poison pill)是一个特殊的对象,告诉消费者“数据已经取完了,你可以退出了”。这类似于C/C++中用null字符作为字符串的结尾。
领取专属 10元无门槛券
私享最新 技术干货