1

So if a program does this:

    static ArrayList<X> a = null;
    static{
            for(;;){X x = new X(); a.add(x)}
          }

and the only operations called after the static initializing, on the shared list, are get() and x.t()

       X x = a.get(i); x.t();

and X doesn't have access to container & is thread safe, that should mean that using Arraylist like this, without synchronization is thread safe, correct?

Sam Adamsh
  • 3,331
  • 8
  • 32
  • 53
  • If the program starts with the `static` block code provides in your example, it will throw a `ExceptionInInitializerError`. – Luiggi Mendoza Nov 05 '12 at 00:41
  • what does `t` do? Or is `t` any arbitrary function we can think of? – Woot4Moo Nov 05 '12 at 00:44
  • change that null to a new Arraylist<>, qestion stands. – Sam Adamsh Nov 05 '12 at 00:44
  • X is thread safe, so it doesn't matter what t does, its a public thread safe method inside X, operating entirely on x state. – Sam Adamsh Nov 05 '12 at 00:45
  • 1
    I don't think that is true, what if X.t modifies the container? – Woot4Moo Nov 05 '12 at 00:46
  • ok, sure. i should say in the qustion that X doesn't have access to container. – Sam Adamsh Nov 05 '12 at 00:49
  • Please modify the question to reflect that. – Woot4Moo Nov 05 '12 at 00:50
  • Not neccesarily. Two or more threads could do this: `public void someMethod(int x) { X x = a.get(x); a.remove(x); }` in order to make this method thread safe, you should synchronize it yourself. The answer here is that the collection itself it's synchronized, but that doesn't save it for two or more threads to access and modify it's contents in a synchronized way. – Luiggi Mendoza Nov 05 '12 at 00:59

4 Answers4

6

If nothing is modifying the ArrayList than there is no reason that you should be worried about it's thread-safety.

That static block is thread-safe by default, because it's ran only once when the class is loaded (for initialization).

Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
  • Agree. We just dont know what `t` does – Woot4Moo Nov 05 '12 at 00:43
  • ... but if you can't *guarantee* that nothing is modifying the `ArrayList`, then I would argue that you *should* be worried about its thread safety. – Daniel Pryden Nov 05 '12 at 18:17
  • @DanielPryden: I agree with that. But it's not mentioned anywhere in the OP. My answer was based on "and the only operations called after the static initializing, on the shared list, are get() ...". – Bhesh Gurung Nov 05 '12 at 18:27
6

If the intention is for the list to not be modified once it is created, then enforce that: wrap the ArrayList in a Collections.unmodifiableList().

Better yet, if you have Guava available, use an ImmutableList.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
1

Vector is the synchronized collection you want.

Just because the elements of the Collection are thread safe does not guarantee that the container itself is thread safe. Based on my understanding of concurrency.

If t modifies the backing Collection it is not thread safe. For instance t is defined as follows:

this.list.remove(this.x);

It would not be safe.

Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
  • No, `Vector` is not the answer. Please read [here](http://javapapers.com/core-java/java-collection/difference-between-vector-and-arraylist-in-java/). – Luiggi Mendoza Nov 05 '12 at 00:50
  • 2
    @LuiggiMendoza if that was the reason for a down vote that is suspect at best. A Vector is a perfectly legitimate collection to use in terms of a synchronization problem. – Woot4Moo Nov 05 '12 at 00:52
  • Down vote was mine. You should always prefer `Collections.synchronizedList(new ArrayList()))` over `Vector` in modern Java because it makes the intent clearer. Better yet, use a lock-free implementation like `CopyOnWriteArrayList`. – Daniel Pryden Nov 05 '12 at 00:55
  • In case you don't believe that `Vector` is not an option: [Why is Java Vector class considered obsolete or deprecated?](http://stackoverflow.com/q/1386275/1065197). – Luiggi Mendoza Nov 05 '12 at 00:55
  • 1
    @LuiggiMendoza Oracle : http://docs.oracle.com/javase/7/docs/api/java/util/Vector.html does not have it deprecated so your argument is invalid on this one. – Woot4Moo Nov 05 '12 at 18:48
  • It's not in the JavaSE Docs but Java people says that `Vector` class is deprecated and you should not use it. You can google this and find lot of info about this (and I mean almost every people will say the same). – Luiggi Mendoza Nov 05 '12 at 18:53
1

Thread-safety is only an issue on writable objects. Once initialised, your ArrayList is immutable - thus thread safe. Consider using unmodifiable wrappers around your arraylist - it will

  1. make clear the array is not meant to be modified
  2. prevent accidental modifications in the future

Just for sake of completeness, please be aware of the fact that, while operations on the ArrayList are threadsafe, operation on the elements are not.

thedayofcondor
  • 3,860
  • 1
  • 19
  • 28