我应该在java中选择哪个集合?
我需要一个集合来存储来自多个客户端的大量请求,同时我使用一个线程每五秒钟处理一次存储的所有请求。那么,我应该在java中选择哪个集合来获得最佳效率?显然,集合应该是线程安全的,并且每五秒钟轮询所有元素的效率很高,对吗?我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。您可以尝试在这种情况下使用 由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留时间最长的元素。尾巴 queue是在队列上停留时间最短的元素。 在队列的尾部插入新元素,然后 检索操作获取队列头部的元素 这是一个经典的“有界缓冲区”,其中包含一个固定大小的数组 生产商插入的元素和消费者提取的元素。一旦 创建时,无法更改容量。尝试放置一个元素 进入满队列将导致操作阻塞;试图 从空队列中获取元素将类似地阻塞 其中有一个方法,该方法将在不消耗CPU周期的情况下进行阻塞,直到将项目添加到队列中。而且它是线程安全的。您可以尝试在这种情况下使用 由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留时间最长的元素。尾巴 queue是在队列上停留时间最短的元素。 在队列的尾部插入新元素,然后 检索操作获取队列头部的元素 这是一个经典的“有界缓冲区”,其中包含一个固定大小的数组 生产商插入的元素和消费者提取的元素。一旦 创建时,无法更改容量。尝试放置一个元素 进入满队列将导致操作阻塞;试图 从空队列中获取元素将类似地阻塞我应该在java中选择哪个集合?,java,multithreading,collections,Java,Multithreading,Collections,我需要一个集合来存储来自多个客户端的大量请求,同时我使用一个线程每五秒钟处理一次存储的所有请求。那么,我应该在java中选择哪个集合来获得最佳效率?显然,集合应该是线程安全的,并且每五秒钟轮询所有元素的效率很高,对吗?我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。我建议使用以时间戳为键、以请求对象为值的静态ConcurrentHashmap。您可以尝试在这种情况下使用 由数组支持的有界阻塞队列。这个队列命令 元素FIFO(先进先出)。排在前面的是 已在队列上停留
其中有一个方法,该方法将在不消耗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(条目));
}
}
我为这种情况编写了一个无锁的双缓冲列表。从本质上讲,您可以从多个线程向它写入,并且写入将累积。当读取时,返回整个列表,同时以线程安全的方式创建一个新列表供写入程序写入
这与任何类型的阻塞队列
之间的关键区别在于,对于队列
,您需要