我应该在java中选择哪个系列?

时间:2013-10-23 14:09:45

标签: java multithreading collections

我需要一个集合来存储来自许多客户端的大量请求,同时我使用一个线程处理每五秒钟存储的所有请求。那么我应该在java中选择哪个集合以获得最佳效率?很明显,该集合应该是线程安全的,并且每五秒轮询所有元素的效率,对吗?

3 个答案:

答案 0 :(得分:4)

在这种情况下,您可以尝试使用ArrayBlockingQueue

  

由数组支持的有界阻塞队列。这个队列命令   元素FIFO(先进先出)。队列的负责人就是这样   已经在队列中时间最长的元素。尾巴的   queue是队列中最短时间的元素。   在队列的尾部和队列中插入新元素   检索操作获取队列头部的元素。

     

这是一个经典的“有界缓冲区”,其中包含固定大小的数组   生产者插入并由消费者提取的元素。一旦   创建后,容量无法改变。试图放置一个元素   进入一个完整的队列将导致操作阻塞;尝试去   从空队列中取一个元素同样会阻塞。

这里有一个 take 方法,它会在不消耗CPU周期的情况下阻塞,直到项目被添加到队列中。它是线程安全的。

答案 1 :(得分:1)

我为这种情况写了一个无锁DoubleBufferedList。从本质上讲,您可以从多个线程写入它,并且写入将累积。当读取出现时,返回整个列表,同时以线程安全的方式,为写入者创建一个新列表。

BlockingQueue与任何Queue之间的重要区别在于,public class DoubleBufferedList<T> { // Atomic reference so I can atomically swap it through. // Mark = true means I am adding to it so momentarily unavailable for iteration. private AtomicMarkableReference<List<T>> list = new AtomicMarkableReference<>(newList(), false); // Factory method to create a new list - may be best to abstract this. protected List<T> newList() { return new ArrayList<>(); } // Get and replace with empty the current list - can return null - does not mean failed. public List<T> get() { // Atomically grab and replace the list with an empty one. List<T> empty = newList(); List<T> it; // Replace an unmarked list with an empty one. if (!list.compareAndSet(it = list.getReference(), empty, false, false)) { // Failed to replace! // It is probably marked as being appended to but may have been replaced by another thread. // Return empty and come back again soon. return Collections.<T>emptyList(); } // Successfull replaced an unmarked list with an empty list! return it; } // Grab and lock the list in preparation for append. private List<T> grab() { List<T> it; // We cannot fail so spin on get and mark. while (!list.compareAndSet(it = list.getReference(), it, false, true)) { // Spin on mark - waiting for another grabber to release (which it must). } return it; } // Release the list. private void release(List<T> it) { // Unmark it - should this be a compareAndSet(it, it, true, false)? if (!list.attemptMark(it, false)) { // Should never fail because once marked it will not be replaced. throw new IllegalMonitorStateException("It changed while we were adding to it!"); } } // Add an entry to the list. public void add(T entry) { List<T> it = grab(); try { // Successfully marked! Add my new entry. it.add(entry); } finally { // Always release after a grab. release(it); } } // Add many entries to the list. public void add(List<T> entries) { List<T> it = grab(); try { // Successfully marked! Add my new entries. it.addAll(entries); } finally { // Always release after a grab. release(it); } } // Add a number of entries. @SafeVarargs public final void add(T... entries) { // Make a list of them. add(Arrays.<T>asList(entries)); } } 您需要一次一个地轮询每个条目。这个结构一次性为您提供整个累积列表,包含自您上次查看以来累积的所有内容。

{{1}}

答案 2 :(得分:0)

以我的建议为基础,将时间戳作为键,请求对象作为值的静态ConcurrentHashmap。