0

Does anyone know why should I (for example) put my List inside Collections.syncrhonizedList() instead of Collections.synchronizedCollection()? Do they work the same? Same applies to Map,Set.

Another thing. Why there isn't Collections.synchronizedQueue()?

Ana Maria
  • 475
  • 2
  • 11
  • 1
    For starters, `synchronizedCollection` returns `Collection`. So what if you wanted to do `List list = Collections.synchronizedCollection(anotherList)`. It would not compile because the method doesn't necessarily return a list. – Michael Aug 24 '20 at 11:46
  • Oh yeah right.. But why is there is no synchronizedQueue then? – Ana Maria Aug 24 '20 at 11:57
  • 2
    Most queues are going to need to be thread-safe to begin with. A non-thread-safe queue is not going to be very useful. So no need for a wrapper for one. The JDK does not aim to provide absolutely everything, only the most broadly useful things. – Michael Aug 24 '20 at 12:01
  • 1
    One minor observation: `Map` doesn't implement `Collection` so you can't use `Collections.synchronizedCollection()` for maps. – Paul Aug 24 '20 at 12:10
  • @Paul nice observation, true.. – Ana Maria Aug 24 '20 at 12:57
  • @Michael Actually I just checked, synchronizedCollection returns me same collection I wrapped it with. So it DOES compile I hate to tell you. It doesn't just return Collection. – Ana Maria Aug 24 '20 at 13:09
  • //1st line: ArrayList a = new ArrayList(); //2nd line: ArrayList b = new ArrayList(Collections.synchronizedList(a)); – Ana Maria Aug 24 '20 at 13:09
  • 2
    @AnaMaria Doing that is completely pointless. You are not making use of the synchronized list at all. The 2nd new ArrayList that you create is copying all the elements of the 1st. You are not left with a thread-safe collection. You may as well call `ArrayList b = new ArrayList(a)`. The result is identical. – Michael Aug 24 '20 at 13:19

1 Answers1

2

When you are using synchronizedCollection() to synchronize an ArrayList, the list-specific methods are not synchronized, so the more concrete method, the better. Beware that method Collections.synchronizedList() will synchronize all the accesses to the backed list except while iterating which still needs to be done within a synchronized block with the synchronized List instance as object's monitor. One more thing, when you create synchronized collection using Collections.synchronizedCollection like this :

Collection c = Collections.synchronizedCollection(yourCollection);

Then, according to documentation, the returned collection does not pass the hashCode and equals operations through to the backing collection, but relies on Object's equals and hashCode methods. This is necessary to preserve the contracts of these operations in the case that the backing collection is a set or a list.

Nemanja
  • 3,295
  • 11
  • 15
  • This seems to imply that there is a danger of calling an synchronized method, and there isn't. In such a case, the list is encapsulated in the synchronized collection. The return type is `Collection`. You couldn't even cast the returned object to a List, because it isn't one. – Michael Aug 24 '20 at 12:13
  • 2
    `ArrayList` wrapped in `synchronizedCollection` has no list-specific methods, rather than list-specific methods not being synchronized. Because it's a `Collection`, not a `List`. –  Aug 24 '20 at 12:45