Thread-safe iteration over a collection

后端 未结 8 1199
情歌与酒
情歌与酒 2020-12-05 05:21

We all know when using Collections.synchronizedXXX (e.g. synchronizedSet()) we get a synchronized \"view\" of the underlying collection.

Ho

8条回答
  •  攒了一身酷
    2020-12-05 06:04

    This Question is rather old (sorry, i am a bit late..) but i still want to add my Answer.

    I would choose your second choice (i.e. Clone the collection before calling iterator()) but with a major twist.

    Asuming, you want to iterate using iterator, you do not have to coppy the Collection before calling .iterator() and sort of negating (i am using the term "negating" loosely) the idea of the iterator pattern, but you could write a "ThreadSafeIterator".

    It would work on the same premise, coppying the Collection, but without letting the iterating class know, that you did just that. Such an Iterator might look like this:

    class ThreadSafeIterator implements Iterator {
        private final Queue clients;
        private T currentElement;
        private final Collection source;
    
        AsynchronousIterator(final Collection collection) {
            clients = new LinkedList<>(collection);
            this.source = collection;
        }
    
        @Override
        public boolean hasNext() {
            return clients.peek() != null;
        }
    
        @Override
        public T next() {
            currentElement = clients.poll();
            return currentElement;
        }
    
        @Override
        public void remove() {
            synchronized(source) {
                source.remove(currentElement);
            }
        }
    }
    

    Taking this a Step furhter, you might use the Semaphore Class to ensure thread-safety or something. But take the remove method with a grain of salt.

    The point is, by using such an Iterator, no one, neither the iterating nor the iterated Class (is that a real word) has to worrie about Thread safety.

提交回复
热议问题