繁体   English   中英

并发ArrayList

[英]Concurrent ArrayList

我需要一个类似ArrayList的结构,只允许以下操作

  • get(int index)
  • add(E element)
  • set(int index, E element)
  • iterator()

由于在许多地方使用了迭代器,因此使用Collections#synchronizedList会容易出错。 该列表可以增长到几千个元素并得到很多使用,所以我很确定, CopyOnWriteArrayList会太慢。 我会从它开始,以避免过早的优化,但我敢打赌它不会很好。

大多数访问将是单线程读取。 所以我问这是什么样的数据结构。


我虽然将synchronizedList包装在提供同步迭代器的东西中,但是由于ConcurrentModificationException ,它不会。 对于并发行为,我显然需要后续读取和迭代器可以看到所有更改。

迭代器不必显示一致的快照,它可能会或可能不会通过set(int index, E element)查看更新set(int index, E element)因为此操作仅用于替换具有其更新版本的项目(包含一些添加的信息,与迭代器的用户无关)。 这些项目完全不可变。


我清楚地说明了为什么CopyOnWriteArrayList不会这样做。 ConcurrentLinkedQueue是不可能的,因为它缺少索引访问。 我只需要几个操作而不是完全成熟的ArrayList 因此,除非任何与Java并发列表相关的问题与此问题重复,否则这个问题不是。

在您的情况下,您可以使用ReadWriteLock访问支持的列表,这允许多个线程读取您的列表。 只有当一个线程需要写访问时,所有读者 - 线程必须等待操作完成。 JavaDoc让它变得清晰:

ReadWriteLock维护一对关联的锁,一个用于只读操作,另一个用于写入。 只要没有写入器,读锁定可以由多个读取器线程同时保持。 写锁是独占的。

这是一个示例:

public class ConcurrentArrayList<T> {

    /** use this to lock for write operations like add/remove */
    private final Lock readLock;
    /** use this to lock for read operations like get/iterator/contains.. */
    private final Lock writeLock;
    /** the underlying list*/
    private final List<T> list = new ArrayList();

    {
        ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
        readLock = rwLock.readLock();
        writeLock = rwLock.writeLock();
    }

    public void add(T e){
        writeLock.lock();
        try{
            list.add(e);
        }finally{
            writeLock.unlock();
        }
    }

    public void get(int index){
        readLock.lock();
        try{
            list.get(index);
        }finally{
            readLock.unlock();
        }
    }

    public Iterator<T> iterator(){
        readLock.lock();
        try {
            return new ArrayList<T>( list ).iterator();
                   //^ we iterate over an snapshot of our list 
        } finally{
            readLock.unlock();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM