简体   繁体   中英

Can ArrayList be used for readonly purpose in multithreaded environment?

I have few ArrayList<T> containing user defined objects (eg List<Student>, List<Teachers> ). The objects are immutable in nature, ie no setters are provided - and also, due to the nature of the problem, "no one" will ever attempt to modify these objects. Once the 'ArrayList' is populated, no further addition/removal of objects is allowed/possible. So List will not dynamically change.

With such given condition, can this data structures (ie ArraList ) be safely used by multiple threads (simultaneously)? Each of the thread will just read the object-properties, but there is no "set" operation possible.

So, my question is can I rely on ArrayList ? If not, what other less expensive data structures can be used in such scenario?

You can share any objects or data structures between threads if they are never modified after a safe publication . As mentioned in the comments, there must be a * happen-before* relationship between the writes that initialize the ArrayList and the read by which the other threads acquire the reference.

Eg if you setup the ArrayList completely before starting the other threads or before submitting the tasks working on the list to an ExecutorService you are safe.

If the threads are already running you have to use one of the thread safe mechanisms to hand-over the ArrayList reference to the other threads, eg by putting it on a BlockingQueue .

Even simplest forms like storing the reference into a static final or volatile field will work.

Keep in mind that your precondition of never modifying the object afterwards must always hold. It's recommended to enforce that constraint by wrapping the list using Collections.unmodifiableList(…) and forget about the original list reference before publishing:

class Example {
  public static final List<String> THREAD_SAFE_LIST;
  static {
    ArrayList<String> list=new ArrayList<>();
    // do the setup
    THREAD_SAFE_LIST=Collections.unmodifiableList(list);
  }
}

or

class Example {
  public static final List<String> THREAD_SAFE_LIST
    =Collections.unmodifiableList(Arrays.asList("foo", "bar"));
}

Yes, you should be able to pass the array into each thread. There should be no access errors so long as the array is finished being written to before any thread is possibly getting the information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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