我应该在java中选择哪个集合?

我应该在java中选择哪个集合?,java,multithreading,collections,Java,Multithreading,Collections,我需要一个集合来存储来自多个客户端的大量请求,同时我使用一个线程每五秒钟处理一次存储的所有请求。那么,我应该在java中选择哪个集合来获得最佳效率?显然,集合应该是线程安全的,并且每五秒钟轮询所有元素的效率很高,对吗?我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。您可以尝试在这种情况下使用 由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留

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

我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。

我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。

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

由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留时间最长的元素。尾巴 queue是在队列上停留时间最短的元素。 在队列的尾部插入新元素,然后 检索操作获取队列头部的元素

这是一个经典的“有界缓冲区”,其中包含一个固定大小的数组 生产商插入的元素和消费者提取的元素。一旦 创建时,无法更改容量。尝试放置一个元素 进入满队列将导致操作阻塞;试图 从空队列中获取元素将类似地阻塞

其中有一个方法,该方法将在不消耗CPU周期的情况下进行阻塞,直到将项目添加到队列中。而且它是线程安全的。

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

由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留时间最长的元素。尾巴 queue是在队列上停留时间最短的元素。 在队列的尾部插入新元素,然后 检索操作获取队列头部的元素

这是一个经典的“有界缓冲区”,其中包含一个固定大小的数组 生产商插入的元素和消费者提取的元素。一旦 创建时,无法更改容量。尝试放置一个元素 进入满队列将导致操作阻塞;试图 从空队列中获取元素将类似地阻塞


其中有一个方法,该方法将在不消耗CPU周期的情况下进行阻塞,直到将项目添加到队列中。而且它是线程安全的。

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

这与任何类型的
阻塞队列
之间的关键区别在于,使用
队列
时,您需要一次轮询每个条目。这个结构一次为您提供了整个累计列表,其中包含自上次查看以来累计的所有内容

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));
  }

}
公共类双缓冲列表{
//原子引用,所以我可以通过原子交换它。
//Mark=true意味着我正在添加它,因此暂时无法用于迭代。
私有AtomicMarkableReference列表=新的AtomicMarkableReference(newList(),false);
//工厂方法创建一个新列表-最好将其抽象出来。
受保护列表newList(){
返回新的ArrayList();
}
//获取并替换为空当前列表-可以返回null-并不意味着失败。
公共列表get(){
//原子地抓取列表并用空列表替换。
List empty=newList();
列出它;
//将未标记的列表替换为空列表。
如果(!list.compareAndSet(it=list.getReference(),空,假,假)){
//更换失败!
//它可能被标记为追加,但可能已被另一个线程替换。
//空着回来,很快再回来。
返回集合。emptyList();
}
//成功将未标记的列表替换为空列表!
归还它;
}
//抓取并锁定列表以准备追加。
私有列表抓取(){
列出它;
//我们不能失败,所以我们要继续努力。
而(!list.compareAndSet(it=list.getReference(),it,false,true)){
//在标记上旋转-等待另一个抓取器释放(必须释放)。
}
归还它;
}
//发布列表。
私人无效释放(列出它){
//取消标记-这应该是一个比较数据集(it、it、true、false)?
if(!list.attemptMark(it,false)){
//不应出现故障,因为一旦标记,将无法更换。
抛出新的IllegalMonitorStateException(“它在我们添加到它时发生了更改!”);
}
}
//在列表中添加一个条目。
公共无效添加(T条目){
List it=grab();
试一试{
//成功标记!添加我的新条目。
添加(条目);
}最后{
//总是在抓取后释放。
释放(it);
}
}
//向列表中添加许多条目。
公共作废添加(列表条目){
List it=grab();
试一试{
//成功标记!添加我的新条目。
it.addAll(条目);
}最后{
//总是在抓取后释放。
释放(it);
}
}
//添加一些条目。
@安全变量
公共最终作废添加(T…条目){
//列一张清单。
添加(Arrays.asList(条目));
}
}

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

这与任何类型的
阻塞队列
之间的关键区别在于,对于
队列
,您需要