Is iteration via Collections.synchronizedSet(…).forEach() guaranteed to be thread safe?

前端 未结 3 1926
后悔当初
后悔当初 2021-02-02 09:00

As we know, iterating over a concurrent collection is not thread safe by default, so one cannot use:

Set set = Collections.synchronizedSet(new HashSet&l         


        
3条回答
  •  梦谈多话
    2021-02-02 09:42

    As @Holger said, the doc clearly says user must manually synchronize collections returned by Collections.synchronizedXyz() when tranversing it via Iterator:

    It is imperative that the user manually synchronize on the returned collection when traversing it via Iterator, Spliterator or Stream:

    Collection c = Collections.synchronizedCollection(myCollection);
     ...
    synchronized (c) {
        Iterator i = c.iterator(); // Must be in the synchronized block
        while (i.hasNext())
           foo(i.next());
    }
    

    I want to explain a bit more about code.

    Consider Collections.synchronizedList() method. It returns Collections.SynchronizedList class instance, which extends SynchronizedCollection which defines iterator() as follows:

    public Iterator iterator() {
        return c.iterator(); // Must be manually synched by user!
    }
    

    Compare this with other methods of SynchronizedCollections, for example:

    public String toString() {
        synchronized (mutex) {return c.toString();}
    }
    

    Thus SynchronizedList inherits iterator() from SynchronizedCollection, which needs to be synched manually by user.

提交回复
热议问题