我必须编写一个需要列表的程序。此列表在其实现中需要是线程安全的(主要是为了避免ConcurrentModificationException),但是ALSO需要允许
出于API原因,要应用Collections.sort()
方法。
CopyOnWriteArrayList实现了前者,但不是后者,我能找到的其他实现允许后者而不是前者。
Java是否有适合我的列表实现?
编辑:需要注意的一点是,遗憾的是我的代码需要与Java 6兼容。
答案 0 :(得分:4)
我想知道这在概念层面上是否真的可行:为了使 sort 操作保持一致,我希望整个列表可以阻止任何添加/在排序进行时删除。
但Collections.sort()不知道在完成工作时需要锁定整个列表。你给它一个列表,如果另一个线程试图同时修改列表...祝你好运。
或者如果你颠倒了观点:一个"线程安全"列表明白它现在正处于排序过程中;所以 - 一些访问(如交换元素)很好;但其他(如添加/删除)元素不是?!
换句话说:我认为你只能做到这一点:选择任何一个"线程安全的"列表实现;然后你必须把你自己的包装放到
当然,对于" 2。&#34 ;;你可以自由转向Collections.sort()。
或者,如果您使用的是Java8 - 您可以使用CopyOnWriteArrayList及其已经实现的sort()方法(这有点证明了我的观点:如果,您只能进行正确的排序在运行排序操作时拥有列表!)。
发表您的最新评论:当然,您可以手动" backport"将CopyOnWriteArrayList的Java8版本导入您的环境并使用它;但当然,这不会有所帮助;据我所知,Java6-Collections.sort()将不从该类调用新的sort()方法。
所以,似乎你的要求总和无法解决;而且你必须咬紧牙关并在自己的代码中完成大部分工作。
答案 1 :(得分:2)
好吧,CopyOnWriteArrayList在排序时锁定整个集合(用于插入)。否?
看起来你对CopyOnWriteArrayList很满意。以下是此课程的片段 -
public void sort(Comparator<? super E> c) {
final ReentrantLock lock = this.lock;
lock.lock();**
try {
Object[] elements = getArray();
Object[] newElements = Arrays.copyOf(elements, elements.length);
@SuppressWarnings("unchecked") E[] es = (E[])newElements;
Arrays.sort(es, c);
setArray(newElements);
} finally {
lock.unlock();
}
}
嗯....因为您已经更新了代码需要与Java6兼容的问题,我要说您应该扩展正常列表并使用https://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReadWriteLock.html。在这种类型的锁中,即使某些其他线程已经获得了writeLock,读者也不会被阻止阅读,并且2个线程可以获得“读取”。同时锁定。
顺便说一句,这种技术将要求你的调用者知道不应该调用Collection.sort(...),因为你必须在列表中公开显式的sort()方法。嗯....不确定这是否有用。