ArrayList并发访问 [英] ArrayList concurrent access

查看:105
本文介绍了ArrayList并发访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 ArrayList 不是线程安全的,但我不确定这个的确切含义。

I am aware that ArrayList is not thread safe, but I'm unsure about the exact implications of this.

对于 ThreadA ThreadB 都使用 ArrayList ,哪些情况会导致问题并需要同步?

In the case of ThreadA and ThreadB both using an ArrayList, which of these situations will cause issues and necessitate synchronization?


  1. 两个线程同时读取相同的索引

  2. ThreadA 替换 ThreadB 同时尝试访问的元素,假设您不关心 ThreadB 获取旧元素或新元素。

  1. Both threads simultaneously reading the same index
  2. ThreadA replacing an element which ThreadB is attempting to access simultaneously, assuming that you don't care whether or not ThreadB gets the old or the new element.


推荐答案


两个线程同时读取相同的索引

Both threads simultaneously reading the same index

多个线程可以从常见的 ArrayList 中读取 / em>该列表是由分叉 ThreadA ThreadB 的线程构建的,列表是完全构造和加载的在线程被分叉之前。

It is okay for multiple threads to be reading from common ArrayList if the list was constructed by the thread that forked the ThreadA and ThreadB and the list is fully constructed and loaded before the threads were forked.

这样做的原因是有一个先前发生的保证,一个线程和分叉它的线程的内存。例如,如果 ThreadC 构建 ArrayList ,那么 之后 ThreadA ThreadB 是分叉的,然后无法保证A和B将完全看到 ArrayList - 如果有的话。

The reason for this is that there is a happens-before guarantee with a thread and the memory of the thread that forked it. If, for example, ThreadC builds the ArrayList but after ThreadA and ThreadB are forked, then there is no guarantee that A and B will fully see the ArrayList -- if at all.

如果不是这种情况,则需要同步列表。请参阅下文。

If this is not the case then you will need to synchronize the list. See below.


ThreadA更改ThreadB尝试同时访问的元素,假设您不关心ThreadB是否获取旧元素或新元素。

ThreadA changing an element which ThreadB is attempting to access simultaneously, assuming that you don't care whether or not ThreadB gets the old or the new element.

一旦你谈到在并发设置中对列表的修改,那么你必须在该列表上同步无法保证修改将被发布,并且可能会部分发布可能导致数据异常的列表。正如@Marko所说,它的内部状态可能不一致。

Once you talk about modifications to the list in a concurrent setting, then you must synchronize on that list otherwise there is no guarantee that the modifications will be published and there are chances that the list could be partially published which could cause data exceptions. As @Marko puts it, its internal state may be inconsistent.

你可以使用设计的 CopyOnWriteArrayList 对于少数更新和许多读取,使用 Collections.synchronizedList(...)使列表受到保护,您可以始终在中访问列表synchronized 块(对于所有写入读取),或者您可以切换到使用并发集合,例如 ConcurrentSkipList 或某事。

You can either use a CopyOnWriteArrayList which is designed for few updates and many reads, use Collections.synchronizedList(...) to make your list be protected, you can access the list always in a synchronized block (for all writes and reads), or you can switch to using a concurrent collection such as ConcurrentSkipList or something.


ThreadA更改ThreadB试图同时访问的元素

ThreadA changing an element which ThreadB is attempting to access simultaneously

这有点含糊不清。如果您正在谈论,例如,在列表中存储对象,然后更改恰好存储在列表中的对象,那么您将不会在列表上出现同步问题但是您将与对象有同步问题。如果列表的数据没有变化那么它就没问题了。但是,如果您需要保护对象,则对象中的 AtomicReference< YourObject> volatile 字段列表,或者需要其他同步来确保在线程之间发布更改。

This is somewhat ambiguous. If you are talking about, for example, storing objects in the list and then changing the objects that happen to be stored in the list then you are not going to have a synchronization problem on the list but you will have a synchronization problem with the object. If the list's data is not changing then it will be fine. However, if you need to protect the object then either a list of AtomicReference<YourObject>, volatile fields in the object, or other synchronization is required to make sure the changes are published between the threads.

这篇关于ArrayList并发访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆