我正在尝试了解多线程。假设我有一个类,它有一个向ConcurrentHashMap添加值的方法。
public void add(ConcurrentHashMap<Integer,String> map){
if(!map.containsKey(1){
map.put(1,"test");
}
}
在添加元素时,如何确保不同的线程不删除特定值或删除整个地图。
我尝试在添加方法中同步(map)但这不起作用。
编辑1: 我没有正确构建它。我的意思是,如果其他一些线程使地图为null,我无法访问使其为null的代码。 如何在add方法中避免空指针异常。 我可以在输入方法后测试它为null但是如果在检查之后但在我向其添加内容之前它变为null。
答案 0 :(得分:1)
首先,您无法删除整个地图&#39;在Java中。如果地图变成垃圾,它就变成了垃圾。其次,如果两个线程竞争,某事就会发生。映射将始终有效,并显示两个线程以某种顺序执行其操作的结果。所有并发映射都是为了 - 确保映射有效且一致,而不需要您对其上的操作进行同步。
答案 1 :(得分:0)
如果要阻止包含对Map
(或任何其他对象类型)的引用的变量变为null,则需要同步读取和写入该变量的所有内容。
这将产生并发瓶颈,并否定使用ConcurrentHashMap
的任何并发优势。
这里真正的问题是某些东西首先为变量赋值null。这使得在线程之间共享Map
非常困难。这可能是您设计中的一个缺陷。
这是一个最好通过消除分配的需要解决的问题。 (或者,如果是偶然的,找到并解决原因。)不要尝试通过同步来修复它。它是一种创可贴解决方案,它将使您的代码更复杂,更少并发。
我无法访问使其为空的代码。
你有一个严重的问题,因为&gt;&gt;那&lt;&lt;代码是&#34;问题&#34;是,并修复它要改变&gt;&gt;那&lt;&lt;代码。
(或者,我猜,您可以声明自己的final Map ...
变量,从您无法更改的代码中删除的狡猾变量初始化它,然后使用您的变量。)
答案 2 :(得分:0)
这里,map
只是对堆上实际对象存储的引用。在Java中,您无法手动删除堆上的对象,而是垃圾收集器可能会删除未被其他任何内容引用的对象。
当您调用add
时,方法块中的代码实际引用了该对象。所以永远不会是null
。此外,您应该使用putIfAbsent
使操作成为原子。