【发布时间】:2016-06-09 15:56:33
【问题描述】:
问题:维护一个具有固定容量(比如 2 个元素)的集合,可以同时跨 100 多个线程访问。
始终存储最近线程中的最新元素。存储它们后,编写一个方法来检查所有这些元素是否重复。
我的解决方案:BlockingQueue 固定容量并实现自定义添加方法。
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.Iterator;
public class FixedBlockingQueue<T extends Object> {
final BlockingQueue<T> queue;
private int capacity;
public FixedBlockingQueue(int capacity){
super();
this.capacity = capacity;
queue = new ArrayBlockingQueue<T>(capacity);
System.out.println("Capactiy:"+this.capacity);
}
public void addElement(T element){
try{
if ( queue.size() > capacity - 1 ){
queue.remove();
}
queue.put(element);
for ( Iterator it = queue.iterator(); it.hasNext();){
System.out.println(it.next());
}
System.out.println("________");
}catch(Exception err){
err.printStackTrace();
}
}
public static void main(String args[]){
FixedBlockingQueue<Integer> f = new FixedBlockingQueue<Integer>(2);
for ( int i=0; i< 10; i++){
f.addElement(i);
}
}
}
输出:
0
________
0
1
________
1
2
________
2
3
________
3
4
________
4
5
________
5
6
________
6
7
________
7
8
________
8
9
从输出中,您可以清楚地看到第一个元素被删除,而最近的元素被添加到队列中。
我的疑问:这是好的解决方案吗?还是有其他更好的解决方案,比这更好?
编辑:在这种频繁删除的场景中,ArrayBlockingQueue 是否比 LinkedBlockingQueue 好?
【问题讨论】:
-
您的任务不包括集合应该是线程安全的?因为你的不是。线程可能会在插入时卡住,因为检查是否需要先删除某些东西不是原子的。
-
调用
queue.size()对于链表类型来说是 O(N) - 因为你每次添加时都这样做,所以你并没有真正获得链表的好处。 -
@Matthew 对于
LinkedBlocking(De)Queue(以及此代码中使用的ArrayBlockginQueue)来说,它是O(1),因为它们会在修改集合时存储和更新大小。ConcurrentLinkedQueue和其他一些人确实是 O(n)。
标签: java multithreading collections