Java制作列表的副本是线程安全的吗?
我在Java应用程序中运行多个线程,所有线程都需要访问同一个列表。但是,实际上只有一个线程需要插入/删除/更改列表,其他线程只需要访问它 在其他线程中,我想制作一份列表的副本,以便在需要阅读时使用,但是是否有任何方法可以以线程安全的方式执行此操作?如果我有一种方法,一个元素一个元素地复制列表,而列表发生了变化,那会把它搞砸的,不是吗 编辑: 列表不会经常从中删除,所以如果我只是正常复制它并捕获异常,它会工作吗?如果列表在拷贝的中间增加了,我就错过了,这对功能不会有什么影响。Java制作列表的副本是线程安全的吗?,java,multithreading,list,concurrency,Java,Multithreading,List,Concurrency,我在Java应用程序中运行多个线程,所有线程都需要访问同一个列表。但是,实际上只有一个线程需要插入/删除/更改列表,其他线程只需要访问它 在其他线程中,我想制作一份列表的副本,以便在需要阅读时使用,但是是否有任何方法可以以线程安全的方式执行此操作?如果我有一种方法,一个元素一个元素地复制列表,而列表发生了变化,那会把它搞砸的,不是吗 编辑: 列表不会经常从中删除,所以如果我只是正常复制它并捕获异常,它会工作吗?如果列表在拷贝的中间增加了,我就错过了,这对功能不会有什么影响。 Use Collec
Use Collections.synchronizedList().
例如:
Collections.synchronizedList(new ArrayList<YourClassNameHere>())
Collections.synchronizedList(新的ArrayList())
您可以使用CopyOnWriteArrayList
实现您的目的
CopyOnWriteArrayList
是Java 5并发API中引入的一个并发集合类,以及它在Java中流行的同类ConcurrentHashMap
顾名思义,CopyOnWriteArrayList创建基础文件的副本
带有每个变异操作的ArrayList,例如添加或设置。正常地
CopyOnWriteArrayList非常昂贵,因为它涉及昂贵的
每次写操作都要进行数组复制,但如果
列出迭代次数多于变异次数的列表,例如,你最需要
迭代ArrayList,不要经常修改它
使用此集合,您不应该每次都创建一个新实例。你应该只有一个这样的对象,它会工作。嗯,所以我想你要找的是CopyOnWriteArrayList CopyOnWriteArrayList-ArrayList的一种线程安全变体,其中所有变异操作(添加、设置等)都是通过创建基础数组的新副本来实现的
Ref:您可以使用线程安全的
CopyOnWriteArrayList
,但它会在每个更新过程中创建一个新的
或者,您可以使用readWriteLock,以便在更新使用时,没有人可以读取,而多个线程可以同时读取。根据您的具体使用情况,您可能会受益于以下其中之一:
我决定通过使用一个单独的线程来处理该线程来解决这个问题,如果其他线程想要写入列表或从列表中获取,则可以使用
BlockingQueue
提交给它们。如果他们想要写入列表,它会提交一个包含他们想要写入的内容的对象,如果他们想要读取,它会提交一个未来
,具有列表的线程将填充可能会有用,而不是每次所有读取线程都需要读取列表时制作副本,当单个编写器更改列表时,可能会更有效地制作副本。这就是CopyOnWriteArrayList的策略。您也可以使用ReadWriteLock。我查找了CopyOnWriteArrayList,但我使用的列表将经常写入,因此似乎效率有点低您确定每次写入时复制列表的效率会降低吗,而不是像你愿意的那样在每次读取时复制它?大致说来,写入速率与读取速率大致相同,所以我想它可能会起作用。我将对它进行基准测试,看看它是否足够快。我正在做一个实时游戏,所以速度对我来说很重要。同时也可能会有数百个这样的列表,不会有太大的变化。在列表上迭代时,仍然需要显式同步。