【问题标题】:Iterators on ConcurrentHashMap [duplicate]ConcurrentHashMap 上的迭代器 [重复]
【发布时间】:2013-10-12 20:14:12
【问题描述】:

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

【问题讨论】:

    标签: java multithreading collections concurrency


    【解决方案1】:

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

    【讨论】:

    • 你知道我可以从一个并发对象中创建多少迭代器对象的性能限制吗?因为我的系统中有大约 50 个线程需要 iterator()...
    • @KanagaveluSugumar,您应该将其作为一个单独的问题提出。
    猜你喜欢
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多