2

ConcurrentHashMap javadoc states that

They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.

But below code output results like two threads can run on iterators at the same time.

ConcurrentHashMap<String,Boolean> ref = new ConcurrentHashMap<String,Boolean>();
    new Thread("Insertion"){
        public  void run(){
            for(int i = 0; i < 100; i++){
                try {
                Thread.sleep(1);
                } catch (InterruptedException e) {
                }
                ref.put(""+i,Boolean.TRUE); 
            }
        }
    }.start();


    new Thread("Iterator_1"){
        public  void run(){
            Iterator itr = ref.keySet().iterator();
            try {
                Thread.sleep(100L);
            } catch (InterruptedException e) {
            }
            while(itr.hasNext()){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                }
                System.out.println(Thread.currentThread()+"" + itr.next());
            }
        }
    }.start();


    new Thread("Iterator_2"){
        public  void run(){
            Iterator itr = ref.keySet().iterator();
            try {
                Thread.sleep(100L);
            } catch (InterruptedException e) {
            }
            while(itr.hasNext()){
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                }
                System.out.println(Thread.currentThread()+"" + itr.next());
            }
        }
    }.start();

Output shows both iterators are working together. Please help to understand this javadoc statement.

Thread[Iterator_1,5,main]67
Thread[Iterator_2,5,main]81
Thread[Iterator_1,5,main]2
Thread[Iterator_2,5,main]59
Thread[Iterator_1,5,main]81
Thread[Iterator_2,5,main]40
Matt McHenry
  • 20,009
  • 8
  • 65
  • 64
Kanagavelu Sugumar
  • 18,766
  • 20
  • 94
  • 101

1 Answers1

2

What the javadoc means is that you shouldn't share the same iterator instance across two different threads. In your example, each thread creates its own iterator instance -- this is correct and safe.

What you should not do is this (sleeps removed because they're irrelevant):

final Iterator itr = ref.keySet().iterator();

new Thread("Iterator_1"){
    public  void run(){
        while(itr.hasNext()){
            System.out.println(Thread.currentThread()+"" + itr.next());
        }
    }
}.start();

new Thread("Iterator_2"){
    public  void run(){
        while(itr.hasNext()){
            System.out.println(Thread.currentThread()+"" + itr.next());
        }
    }
}.start();
Matt McHenry
  • 20,009
  • 8
  • 65
  • 64