首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AtomicReference<ArrayList>的困难与选择

AtomicReference<ArrayList>的困难与选择
EN

Stack Overflow用户
提问于 2016-06-25 13:12:54
回答 2查看 5.7K关注 0票数 2

因此,在我为好玩而编写的各种程序中,我遇到了并发修改异常。

在我解决这个问题的天真尝试中,我使用了Atomic而不是某种并发集合。我有点熟悉为什么这是套管错误。本质上,ArrayList的各个元素是不同步的,可以由不同的线程随意修改。

有人能帮我总结一下吗

  • 当我尝试对集合进行原子引用时,会发生什么错误?
  • 什么是对数组或列表的原子引用的合法用例
  • 有什么更好的方法来存储游戏的实例,可供多线程使用

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-25 13:55:35

我想你混淆了ConcurrentModification是什么意思.

最常见的情况是迭代一个集合并在循环中修改它。

例如,如果您执行以下操作

代码语言:javascript
复制
    public static void main(String[] args) {
        List<String> l = new LinkedList<>();
        for(int i=0; i < 100; i++) {
            l.add("banana"+i);
        }

        for (String s : l) {
            if("banana10".equals(s)) {
                l.remove(s);
            }
        }
    }

...this会给你一个ConcurrentModificationException。注意,我没有产生任何线程。

正确的方法如下:

代码语言:javascript
复制
public static void main(String[] args) {
    List<String> l = new LinkedList<>();
    for(int i=0; i < 100; i++) {
        l.add("banana"+i);
    }

    for (Iterator<String> iterator = l.iterator(); iterator.hasNext();) {
        String s = iterator.next();
        if("banana10".equals(s)) {
            iterator.remove();
        }
    }
}

注意,在遍历集合时,使用迭代器来修改集合。

所以,我不认为你有并发问题!

如果希望使集合线程安全,则需要查看线程安全的语义。如果您希望允许多个线程访问同一个集合,那么ConcurrentList将是一种很好的方法。如果需要原子设置的列表引用,则可以使用原子引用。

票数 2
EN

Stack Overflow用户

发布于 2016-06-25 13:48:54

使用AtomicReference存储对象(如集合)不足以使其线程安全。实际上,如果您在AtomicReference中放置的对象不像ArrayList那样是线程安全的,那么如果我们有多个线程试图并发地修改其状态,那么使用它仍然是不安全的。因此,好的方法仍然是在AtomicReference中放入一个不可变的对象,这样它的状态就不能再被多个线程修改了。例如,在集合的情况下,可以对列表使用Collections.unmodifiable*类型的方法(如Collections.unmodifiableList(List) ),以便将集合的不变版本放入AtomicReference

如果您需要线程安全集合,您应该查看包java.util.concurrent中的类,您将发现集合本身是线程安全的。例如,如果您大部分时间阅读并且很少修改您的List,则可以使用线程安全和高效的列表CopyOnWriteArrayList

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38028892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档