有序(自然插入顺序)和线程安全的Java Map

时间:2013-05-30 12:11:42

标签: java multithreading map java.util.concurrent

我有一个遗留应用程序,他们使用ConcurrentHashMap。现在我们知道concurrentHasMap是无序的,但读取最初插入的对象是一项要求。我生产的代码已经存在了一段时间,因此我正在寻找快速替代品来替换集合,这也可以给我订购。基本上寻找一种非侵入性的解决方案,可以最大限度地减少代码更改。我在网上搜索并获得了ConcurrentSkipListMap作为替代方案,但它对我不起作用。原因是,默认情况下它按照键的自然顺序排序,这对我不起作用。由于我的键是字符串,我需要根据插入顺序而不是字符串键将如何在地图中自然排序。

请尽早提出一些替代方案。

由于 Anubhav

2 个答案:

答案 0 :(得分:0)

您应该可以使用LinkedHashMap来保留广告订单,并使用synchronized方法Collections.synchronizedMap(Map map)

public class Test {
  Map<String, String> map = new LinkedHashMap<>();
  Map<String, String> test = Collections.synchronizedMap(map);

  public void test() {
    test.put("Z", "Zed");
    test.put("A", "Ay");
    for (String s : test.keySet()) {
      System.out.println(s);
    }
  }

  public static void main(String args[]) {
    try {
      new Test().test();
    } catch (Throwable t) {
      t.printStackTrace(System.err);
    }
  }

}

打印:

Z
A

根据您的要求。

答案 1 :(得分:0)

您可以自行重新订购密钥。这样的事情可能是可能的。请注意,这不是一个完整的解决方案,需要做很多额外的工作才能正确实现ConcurrentMap

class InsertOrderedMap<K, V> implements ConcurrentMap<K,V> {
  // The actual map holding the data.
  Map<Integer, V> ordered = new ConcurrentSkipListMap<>();
  // Mapping the key to the order.
  Map<K, Integer> reorder = new ConcurrentSkipListMap<>();
  // The next position.
  AtomicInteger next = new AtomicInteger(0);

  @Override
  public V get(Object o) {
    return ordered.get(reorder.get(o));
  }

}

如果两次添加相同的密钥,则必须决定需要执行的操作。值应该在哪个位置,原始位置或新位置?是否应删除原始文件?