【摘要】这是一篇关于Java 集合与队列的插入、删除的性能比较的文章,主要讲述了每一项的不同点,希望能对大家有所帮助。
这两天在写一个java多线程的爬虫,以广度优先爬取网页,设置两个缓存:
• 一个保存已经访问过的URL:vistedUrls
• 一个保存没有访问过的URL:unVistedUrls
需要爬取的数据量不大,对URL压缩后,可以把这两个数据结构都放入内存,vistedUrls很显然用HashSet
纠结unVistedUrls该用什么数据结构,如果用队列的话,并发情况下,队列中可能会用重复的URL,比如一个线程A爬了CSDN的一个URL1,另一个线程B爬了博客园的一个URL2,URL1和URL2的页面都有一个相同的出链URL3,线程A把URL3加入到unVistedUrls的队尾,等待下次爬取,但在URL3被爬取之前,线程B也把URL3加到队尾,这样队列中就有两个相同的URL,可能会导致重复爬取网页,当然可以通过其他方法来保证不会重复爬取。
然后就想能否也用Set来保存未访问的URL,这样在添加新的URL时,自动去重处理了,能够有效保证不爬取重复网页。但是unVistedUrls会有大量的插入和删除操作,我认为对集合进行大量的插入删除性能会比较低,为了测试集合的插入删除性能对比队列低多少,我写了一个简单的并发测试:
复制代码
1 /**
2 * 测试集合与队列的插入与读写性能
3 *
4 * @author jiqunpeng@Gmail.com
5 *
6 */
7 public class SetQueueTest {
8 // 随即数构造器
9 PRivate static Random r = new Random(10);
10 // 控制测试线程停止的原子变量
11 private static AtomicBoolean stop = new AtomicBoolean(false);
12
13 /***
14 * 基类,供测试用
15 *
16 * @author jiqunpeng@gmail.com
17 *
18 */
19 static abstract class Service {
20 // 操作的计数器
21 protected long count = 0;
22
23 // 添加一堆元素,并去一个元素
24 public abstract String addAndPick(List
25
26 // 取一个元素
27 public abstract String pickOne();
28
29 /**
30 * 打印操作次数
31 */
32 public void tell() {
33 System.out.println(this + " :\t" + count);
34 }
35 }
36
37 /***
38 * 采用TreeSet的集合工具
39 *
40 * @author jiqunpeng@gmail.com
来源: http://www.51edu.com/it/bckf/36152.html