Executor Service在多线程环境中清除映射值

时间:2017-08-16 14:37:34

标签: java multithreading executorservice

我有一个情况。我正在使用Executor Service来使用多线程。所以现在我正在尝试向地图添加一个值,并在完成该循环后立即为每个线程清除它。我为此编写了以下代码。

我创建了一个地图,并保存每次迭代的值并清除它。但是因为我正在使用Executor Service创建10thread并将值添加到地图中我相信。这就是为什么我能够看到多个值,即使我只是添加一个值并清除它。

那么如何在循环中清除地图中的每个交易:(

代码:

public class Test1 {
public static void main(String[] args){
    ExecutorService executor = Executors.newFixedThreadPool(10);
    final Multimap<Object, Object> map = Multimaps.synchronizedMultimap(ArrayListMultimap.create());

    final List<String> listA = new ArrayList<String>();
    listA.add("e");
    listA.add("f");
    listA.add("g");
    final List<String> listB = new ArrayList<String>();
    listB.add("e");
    listB.add("f");
    listB.add("g");
    final List<String> listC = new ArrayList<String>();
    listC.add("e");
    listC.add("f");
    listC.add("g");


    for (final String stateId : listA) {
        for (final String gradeList : listB) {
            for (final String subjectList : listC) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                map.clear();
                map.put("f", "hi");
                System.out.println("map before "+map);

                System.out.println("map after "+map);
            }
        });
    }

    }
    }
    executor.shutdown();
    try {
        executor.awaitTermination(24L, TimeUnit.HOURS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

输出:

map before {f=[hi, hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
 map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi, hi]}
map before {f=[hi, hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
 map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi, hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
 map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
 map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map before {f=[hi]}
map before {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}
map after {f=[hi]}

1 个答案:

答案 0 :(得分:2)

简单 - javadoc明确指出:

  

当任何并发操作更新multimap时,此类不是线程安全的。并发读取操作将正常工作。要允许并发更新操作,请通过调用Multimaps.synchronizedListMultimap(com.google.common.collect.ListMultimap)来包装多图。

换句话说:你不能只采取任何方便的集合类并抛出多个线程 - 无需采取进一步的预防措施。