Java 使用threadsafty对concurrentHash映射进行排序

Java 使用threadsafty对concurrentHash映射进行排序,java,multithreading,collections,concurrenthashmap,Java,Multithreading,Collections,Concurrenthashmap,我在“多线程”应用程序中使用“concurrentHashMap”。我能把它按我所描述的分类。但由于我正在将hashmap转换为一个列表,我有点担心它的安全性。我的“ConcurrentHashMap”是一个静态变量,因此我可以保证它只有一个实例。但当我要对它进行排序时,我将其转换为一个列表,然后进行排序,然后将其放回一个新的concurrentHashMap 这是一个多线程活跃的好做法吗 请让我知道你的想法和建议 提前谢谢。如果您没有对其进行太多更改,并且您只想对其进行排序,那么您应该使用一个

我在“多线程”应用程序中使用“concurrentHashMap”。我能把它按我所描述的分类。但由于我正在将hashmap转换为一个列表,我有点担心它的安全性。我的“ConcurrentHashMap”是一个静态变量,因此我可以保证它只有一个实例。但当我要对它进行排序时,我将其转换为一个列表,然后进行排序,然后将其放回一个新的concurrentHashMap

这是一个多线程活跃的好做法吗

请让我知道你的想法和建议


提前谢谢。

如果您没有对其进行太多更改,并且您只想对其进行排序,那么您应该使用一个由**调用包装的**

您的代码如下所示:

public class YourClass {
  public static final Map<Something,Something> MAP = Collections.synchronizedMap( new TreeMap<Something,Something>() );
}
公共类您的类{
publicstaticfinalmap=Collections.synchronizedMap(newtreemap());
}
您应该使用。它是线程安全、快速的,并根据对象的可比较实现维护顺序

我的“ConcurrentHashMap”是一个静态变量,因此我可以保证它只有一个实例。但当我要对它进行排序时,我将其转换为一个列表,然后进行排序,然后将其放回一个新的concurrentHashMap

这不是一个简单的问题

我可以告诉你一个事实,使用ConcurrentHashMap不会使这个线程安全。也不会使用
synchronizedMap
包装器。问题是排序不支持作为单个原子操作。相反,它涉及一系列Map-API操作,它们之间可能有很大的时间间隔

我可以想出两种方法来解决这个问题:

  • 通过使用保持键有序的地图,首先避免排序的需要;e、 g.使用ConcurrentSkipListMap

  • 使用synchronized
    sort
    方法将Map类包装在自定义的同步包装类中。这种方法的问题在于,可能会重新引入通过使用ConcurrentHashMap避免的并发瓶颈



值得指出的是,对
HashMap
ConcurrentHashMap
进行排序没有任何意义,因为这些映射不会保留元素排序的顺序。您可以使用
LinkedHashMap
,它保留了条目插入顺序。

谢谢您的帮助。有没有关于ConcurrentSkipListMap的例子?我从来没用过。如果你有什么东西请告诉我。我将开始工作。@Sam您应该看看可比较的界面。如果地图的每个键都是可比较的类型,则每个put将自动对地图本身进行排序。它的功能和时间复杂度与树形图相似。谢谢Stephan。但是如果我在“Synchronized”块中使用代码,会发生什么呢?原因是我需要确保concurrenthashmap只包含具有线程安全性的已排序列表。在插入到hashmap之前考虑排序值。@Sam-只有在同步块内进行排序时,如果映射的每一次其他使用也在同一对象上同步,那么排序才有帮助。这可能会导致并发瓶颈…感谢您的回答。我从来没有用过这种地图。我将搜索一些示例并查看..如果您有一些示例,请让我知道。我现在将浏览TreeMap API。谢谢。除了并发性,没有排序HashMap这样的东西。您可以将值复制到列表中并对列表进行排序,但当您获取列表值并将其放回HashMap时,它们会返回到哈希顺序。(有LinkedHashMap,但没有并发版本。)@Wyzard-因此,如果我根据我的comparator对其进行排序,并创建一个新的concurrentHashMap,然后将其放入列表中的循环中,它应该以排序方式对吗?如果您将排序列表中的元素放入一个新的concurrentHashMap中,然后在该映射上迭代,您会发现元素的顺序与原始ConcurrentHashMap中的顺序相同,而不是它们在排序列表中的顺序。如果您仔细观察,您会发现它们是按hashCode()方法返回的数字排序的。@Wyzard我甚至不认为您会发现对象是按hashCode()排序的。HashMap和ConcurrentHashMap都有一个方法
int hash(int)
,该方法对键的散列进行散列,特别是为了防止产生分布不均匀的值的类。当然,这不是规范的一部分,但openjdk就是这样。