【问题标题】:Protecting maps against threads in java在java中保护映射免受线程的影响
【发布时间】:2017-02-24 00:37:52
【问题描述】:

我有一种情况,我有一张巨大的地图来维护一些数据。 我的应用程序是多线程的。

一个线程可能会尝试从映射中删除条目,而第二个线程可能会尝试复制映射。 以下是描述我的问题的示例代码。

public class CollectionsTest {
    static Map<String, String> map = new HashMap<>();
    public static void main(String [] args) throws InterruptedException {
        for(long i=0;i<1000000; i++){
            map.put("key"+i, "value"+i);
        }
        Thread t1 = new Thread(new Task1());
        Thread t2 = new Thread(new Task2());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
    private static class Task1 implements Runnable {
        @Override
        public void run() {
            System.out.println("Task 1 start");
            Map<String, String> copy = new HashMap<>(map);
            System.out.println(copy.get("key1"));
            System.out.println("Task 1 done");
        }
    }
    private static class Task2 implements Runnable {
        @Override
        public void run() {
            System.out.println("Task 2 start");
            map.remove("key2");
            System.out.println("Task 2 end");
        }
    }
}

下面是输出

Task 1 start
Task 2 start
Task 2 end
Exception in thread "Thread-0" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
    at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
    at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
    at java.util.HashMap.putMapEntries(HashMap.java:511)
    at java.util.HashMap.<init>(HashMap.java:489)
    at com.alcatel.pma.core.configmgmt.CollectionsTest$Task1.run(CollectionsTest.java:27)
    at java.lang.Thread.run(Thread.java:745)

Process finished with exit code 0

避免这种情况的最佳方法是什么?

【问题讨论】:

标签: java multithreading collections


【解决方案1】:

在多线程环境中处理数据结构时,您基本上有两种选择。

  1. 您选择同步实现,如 ConcurrentHashMap、CopyOnWriteArray 等。这些数据结构旨在同时使用。实现细节差异很大(写入时的数据克隆、锁/信号量、监视器(同步关键字),您必须谨慎选择最合适的结构。

  2. 您可以使用锁(ReentrandRead/WriteLock)或 Java 监视器同步对未同步数据结构的访问。

如果您对并发了解不多,建议您选择第一个选项。如果您想了解很多有关 Java 编程的知识,请选择选项二。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2012-12-20
    • 2017-03-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多