3

If thread A populates an ArrayList (Lets say at startup) and then leaves it for other threads to read (no more writes). In my understanding (in the absense of multithreaded constructs like volatile, synchronised, CAS and others) changes made by thread A to the list may never be visible to other threads. If correct, how does Arraylist ensures that items added to it are visible or it doesn’t provide that guarantee?

Abidi
  • 7,846
  • 14
  • 43
  • 65
  • 2
    It doesn't. You'll need to provide other mechanisms yourself. Like starting the threads after initializing the list, and from the thread that initialized it. – Sotirios Delimanolis Jan 23 '19 at 18:53
  • @SotiriosDelimanolis huh? Are you claiming that if two threads have access to a single `ArrayList` and one modifies it, the second one will not see it? – Fureeish Jan 23 '19 at 18:55
  • @Sotirios, interesting. Starting threads once the list is fully populated would ensure visibility. How is it done, do you have a link to read more on it? – Abidi Jan 23 '19 at 18:59
  • @Fureeish, the second thread *might not* see the first one's writes at all, might see them in a different order than the other does, with respect to each other or to other events, *etc*.. What you describe constitutes a "data race", and programs containing a data race have undefined behavior. – John Bollinger Jan 23 '19 at 19:00
  • Even though all threads share the same resource, the `ArrayList` is not guaranteed to be thread safe in the case of concurrent read/writes. – Dorian Gray Jan 23 '19 at 19:00
  • 1
    https://stackoverflow.com/questions/48255948/is-happens-before-transitive-when-calling-thread-start – Sotirios Delimanolis Jan 23 '19 at 19:01
  • @JohnBollinger it might be just me, but I felt that the original comment simply stated that there is no visibility whatsoever. There is. It's simply not synchonised. If you happen to check 'just once', other Threads might not see the change, and yes, that would fall under data race. While `ArrayList` itself is not thread safe, it does not mean that multiple threads cannot see changes applied to it. – Fureeish Jan 23 '19 at 19:03
  • 1
    @Fureeish no visibility is guaranteed. One thread can append something to an ArrayList and a second one won't ever see it. This is 100% correct and possible. For instance the other thread checks the size of the ArrayList, and the size gets cashed in a cpu register by the compiler. – ciamej Jan 23 '19 at 19:06
  • @ciamej that's interesting. Why would that be allowed? If one Thread outputs `List::size` in a `while(true)` loop, and the second Thread simply appends some elements (assume that `synchronized` is used) in similar loop, is there *really* a possibility, that we'll see only `0`s? – Fureeish Jan 23 '19 at 19:08
  • @Fureeish e.g. `while(1) { for(int i=0;i – ciamej Jan 23 '19 at 19:09
  • @ciamej do you have any sources that would back up that statement? Or course I agree that something like this could be done, but only if it's ensured that no other thread has access to the `arrayList`. That seems silly, especially given how multithreading context is standardised in Java. – Fureeish Jan 23 '19 at 19:12
  • 1
    @Fureeish Actually it's the opposite ;) The compiler is always allowed to assume that the code is run sequentially by a single thread. If you intend to be used by multiple threads you have to provide synchronization. When the compiler sees a piece of code without synchronization it can do with it whatever it pleases just as long the optimized code behaves the same in a single-thread environment. – ciamej Jan 23 '19 at 19:19
  • That does make sense, but some actual sources would be appreciated :> – Fureeish Jan 23 '19 at 19:24
  • 1
    @Fureeish See Table 17.3 in https://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html - it is the closest I was able to find. – ciamej Jan 23 '19 at 19:29

0 Answers0