我在Java应用程序中运行多个线程,并且所有线程都需要访问同一个列表。但是,只有一个线程实际上需要插入/删除/更改列表,而其他线程只需要访问它。
在其他线程中,我希望在需要读取它时为我创建一个列表副本,但有没有办法以线程安全的方式执行此操作?如果我有一个方法来按元素复制列表元素并且列表发生了变化,那么它会搞砸它不会吗?
编辑:
列表不会经常删除,如果我只是正常复制并捕获异常,它会起作用吗?如果列表在副本中间增长并且我错过了它,那么它对功能的影响不会很大
答案 0 :(得分:3)
您可以将CopyOnWriteArrayList
用于您的目的。
CopyOnWriteArrayList
是Java 5 Concurrency API中引入的并发Collection类及其在Java中的流行表兄ConcurrentHashMap
。
顾名思义,CopyOnWriteArrayList创建底层副本 具有每个突变操作的ArrayList,例如添加或设置。一般 CopyOnWriteArrayList非常昂贵,因为它涉及昂贵 每次写入操作的数组副本,但如果你的话,它非常有效 有一个列表,其中迭代次数超过变异,例如你最需要的 迭代ArrayList并且不要经常修改它。
使用此集合,您不应每次都创建新实例。你应该只有一个这样的对象,它会起作用。
答案 1 :(得分:1)
嗯,所以我认为你想要的是 CopyOnWriteArrayList 。
CopyOnWriteArrayList - ArrayList的线程安全变体,其中所有可变操作(添加,设置等)都是通过创建底层数组的新副本来实现的。
答案 2 :(得分:0)
您可以使用线程安全的CopyOnWriteArrayList
,但它会在每次更新过程中创建新的。{/ p>
或者您可以使用readWriteLock,因此当更新使用时,没有人可以读取多个线程可以同时读取。
答案 3 :(得分:0)
根据您的具体用法,您可能会受益于以下其中一种:
答案 4 :(得分:0)
我决定通过一个处理线程的单独线程来解决这个问题,如果他们想要写入列表,或者从列表中获取,则BlockingQueue
用于其他线程提交。如果他们想要写入列表,它将提交一个包含他们想要写的内容的对象,如果他们想要阅读,它将提交一个Future
,该列表中的线程将填充
答案 5 :(得分:-1)
console.log('Starting directory: ${process.cwd()}');
try {
process.chdir('C:\Users\HalvorSD\node-party');
console.log('New directory: ${process.cwd()}');
} catch (err) {
console.error('chdir: ${err}');
}
示例:
Use Collections.synchronizedList().