Java 8 最终允许我们(程序员)在 Java 中创建线程安全的ConcurrentHashSet
。 在此之前,这根本是不可能的。 有一些变种试图简化上述类的实现,其中之一就是使用带有虚拟值ConcurrentHashMap
。 但是,您可能已经猜到,ConcurrentHashMap
的所有即兴创作都有其局限性和风险。
Java 8 允许我们使用keySet(defaultVal)
和newKeySet()
方法来返回 Set,这恰好是一个合适的集合。 这样可以访问用户可以使用的许多必要功能:contains()
,remove()
等。 注意: 这些方法在ConcurrentHashMap
中可用,而不是在ConcurrentMap
接口中可用, 意味着必须创建ConcurrentHashMap
类型的变量,并将其用作引用。 另一种方法是对象的简单转换。
Java 并发 API 中包含许多Collection
类,例如ArrayList
的CopyOnArrayList
,HashMap
的ConcurrentHashMap
和HashSet
的CopyOnWriteArraySet
。 但是,尽管有所有这些示例,但没有类似ConcurrentHashSet
的东西。 许多开发人员说,他们可以使用具有相同值的ConcurrentHashMap
来实现所需的集合,但是这种方法的问题在于,您拥有的是映射而不是集合。 因此,这将导致无法使用伪值对ConcurrentHashMap
执行设置操作。 简而言之,它不是Set
。
还有其他尝试创建ConcurrentHashSet
的即兴创作,但现在它们都已过去,因为 Java 8 添加了newKeySet()
,它返回由ConcurrentHashMap
支持的Set
。
如何在 Java 8 中创建ConcurrentHashSet
ConcurrentHashMap<String, Integer> example = new ConcurrentHashMap<>();
Set<String> exampleSet = example.newKeySet();
exampleSet.add("example");
exampleSet.add("example2");
exampleSet.contains("example2");
exampleSet.remove("example");
在上面的示例中,我们创建了集合,并向其中添加了 2 个元素,检查它是否包含某个元素并删除了某个元素。
注意: 这是在 Java 中创建线程安全Set
的唯一方法。
Java 程序使用java.util.concurrent.ConcurrentHashMap
类上添加的新方法创建ConcurrentHashSet
。
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class Example {
public static void main(String[] args) throws Exception {
ConcurrentHashMap shoesCost = new ConcurrentHashMap<>();
shoesCost.put("Nike", 80);
shoesCost.put("Adidas", 40);
shoesCost.put("Reebok", 76);
Set shoeCostSet = shoesCost.keySet();
shoeCostSet = shoesCost.newKeySet();
System.out.println("before adding element into concurrent set: " + shoeCostSet);
shoeCostSet.add("Puma");
System.out.println("after adding element into concurrent set: " + shoeCostSet);
shoeCostSet.contains("Adidas");
shoeCostSet.remove("Reebok");
}
}
输出:
before adding an element into the concurrent set: [Nike, Adidas, Reebok]
after adding an element into the concurrent set: [Nike, Adidas, Reebok, Puma]