I need to make an ArrayList of ArrayLists thread safe. I also cannot have the client making changes to the collection. Will the unmodifiable wrapper make it thread safe or d
An immutable object is by definition thread safe (assuming no-one retains references to the original collections), so synchronization is not necessary.
Wrapping the outer ArrayList using Collections.unmodifiableList() prevents the client from changing its contents (and thus makes it thread safe), but the inner ArrayLists are still mutable.
Wrapping the inner ArrayLists using Collections.unmodifiableList() too prevents the client from changing their contents (and thus makes them thread safe), which is what you need.
Let us know if this solution causes problems (overhead, memory usage etc); other solutions may be applicable to your problem. :)
EDIT: Of course, if the lists are modified they are NOT thread safe. I assumed no further edits were to be made.
It depends. The wrapper will only prevent changes to the collection it wraps, not to the objects in the collection. If you have an ArrayList of ArrayLists, the global List as well as each of its element Lists need to be wrapped separately, and you may also have to do something for the contents of those lists. Finally, you have to make sure that the original list objects are not changed, since the wrapper only prevents changes through the wrapper reference, not to the original object.
You do NOT need the synchronized wrapper in this case.
The unmodifiable wrapper only prevents changes to the structure of the list that it applies to. If this list contains other lists and you have threads trying to modify these nested lists, then you are not protected against concurrent modification risks.
This is neccessary if:
If you intend to read from the ArrayList by index only you could assume this is thread-safe.
When in doubt, chose the synchronized wrapper.
Not sure if I understood what you are trying to do, but I'd say the answer in most cases is "No".
If you setup an ArrayList of ArrayList and both, the outer and inner lists can never be changed after creation (and during creation only one thread will have access to either inner and outer lists), they are probably thread safe by a wrapper (if both, outer and inner lists are wrapped in such a way that modifying them is impossible). All read-only operations on ArrayLists are most likely thread-safe. However, Sun does not guarantee them to be thread-safe (also not for read-only operations), so even though it might work right now, it could break in the future (if Sun creates some internal caching of data for quicker access for example).
I believe that because the UnmodifiableList wrapper stores the ArrayList to a final field, any read methods on the wrapper will see the list as it was when the wrapper was constructed as long as the list isn't modified after the wrapper is created, and as long as the mutable ArrayLists inside the wrapper aren't modified (which the wrapper can't protect against).