如何同步不可修改的集合 [英] How to synchronize unmodifiable collections

查看:65
本文介绍了如何同步不可修改的集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向外部客户返回类的不可修改的视图(维护一组项目)。

I want to return an unmodifiable view of the class (that maintain a collection of items ) to outside clients .

为了保护并发访问,我需要包装

So to protect concurrent access, I need to wrap the collection in a synchronized wrapper first, then put an unmodifiable wrapper around the version I return to outside threads.

所以我写了下面的代码,不幸的是,它抛出了一个ConcurrentModificationException异常。

So I wrote the following code and unfortunately it is throwing a ConcurrentModificationException. .

import java.util.*;

public class Test {
public static void main(String[] args) {
    // assume c1 is private, nicely encapsulated in some class
    final Collection col1 = Collections.synchronizedCollection(new ArrayList());
    // this unmodifiable version is public
    final Collection unmodcol1 = Collections.unmodifiableCollection(col1);

    col1.add("a");
    col1.add("b");

    new Thread(new Runnable() {
        public void run() {
            while (true) {
                // no way to synchronize on c1!
                for (Iterator it = unmodcol1 .iterator(); it.hasNext(); it.next())
                    ;
            }
        }
    }).start();

    while (true) {
        col1 .add("c");
        col1 .remove("c");
    }
   }
 }

>如何同步不可修改的集合?

So my question is How to synchronize unmodifiable collections ?

添加更多

集合想要遍历其元素

1)它不一定知道它是一个同步的集合和

1) it doesn't necessarily know that it's a synchronized collection and

2)即使它是,它也不能在同步包装器mutex上正确同步以遍历其元素。
Collections.synchronizedCollection中描述的惩罚是非确定性行为。

2) even if it does, it can't correctly synchronize on the synchronization wrapper mutex to iterate over its elements. The penalty, as described in Collections.synchronizedCollection, is non-deterministic behaviour.

根据我的理解在同步的集合上放置不可修改的包装

推荐答案

如果可以确保集合的同步的只读客户端在集合上同步的同一视图:

If you can ensure that read-only clients of the collection synchronize on the collection, synchronize on that same view in your producer:

/* In the producer... */
Collection<Object> collection = new ArrayList<>();
Collection<Object> tmp = Collections.unmodifiableCollection(collection);
Collection<Object> view = Collections.synchronizedCollection(tmp);
synchronized (view) {
  collection.add("a");
  collection.add("b");
}
/* Give clients access only to "view" ... */

/* Meanwhile, in the client: */
synchronized (view) {
  for (Object o : view) {
    /* Do something with o */
  }
}

这篇关于如何同步不可修改的集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆