ConcurrentHashMap上的迭代器

时间:2013-10-06 02:27:12

标签: java multithreading collections concurrency

ConcurrentHashMap javadoc声明

  

它们不会抛出ConcurrentModificationException。但是,迭代器   设计为一次只能由一个线程使用。

但是在代码输出结果下面,两个线程可以同时在迭代器上运行。

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();

输出显示两个迭代器一起工作。请帮助理解这个javadoc声明。

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

1 个答案:

答案 0 :(得分:2)

javadoc意味着你不应该跨两个不同的线程共享相同的迭代器实例。在您的示例中,每个线程都创建自己的迭代器实例 - 这是正确且安全的。

做的是这个(因为它们无关紧要而被删除):

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();