我指的是此处提出的问题,并使用作者代码示例,现在我的问题是
synchronized(synchronizedMap)
,真的有必要吗,因为syncedMap始终会确保没有两个线程试图对其进行read/put
操作,Map
那么为什么需要synchronize
在该地图本身上进行操作呢?非常感谢您的解释。
public class MyClass {
private static Map<String, List<String>> synchronizedMap =
Collections.synchronizedMap(new HashMap<String, List<String>>());
public void doWork(String key) {
List<String> values = null;
while ((values = synchronizedMap.remove(key)) != null) {
//do something with values
}
}
public static void addToMap(String key, String value) {
synchronized (synchronizedMap) {
if (synchronizedMap.containsKey(key)) {
synchronizedMap.get(key).add(value);
}
else {
List<String> valuesList = new ArrayList<String>();
valuesList.add(value);
synchronizedMap.put(key, valuesList);
}
}
}
}
为什么我们需要对其
synchronizemap
本身进行同步?
您可能需要在一个已经同步的集合上进行同步,因为您正在对该集合执行两个操作-在您的示例中,是a containsKey()
然后是aput()
。您试图在 _调用_集合的代码中防止竞争情况。另外,在这种情况下,该块还保护值,以便多个线程可以将其值添加到这些未同步的集合中。
__synchronized``ArrayList
如果您查看链接到的代码,他们将首先检查键的存在,如果键不存在,则将值放入映射中。您需要防止2个线程的一个重要的生存确认,然后 两个
人投入的地图。比赛是哪一个将第一名,哪个人将覆盖前一名。
同步的集合可保护自己免受多个线程破坏映射本身的侵害。它 不能 防止围绕多次调用该映射的逻辑竞争条件。
synchronized (synchronizedMap) {
// test for a key in the map
if (synchronizedMap.containsKey(key)) {
synchronizedMap.get(key).add(value);
} else {
List<String> valuesList = new ArrayList<String>();
valuesList.add(value);
// store a value into the map
synchronizedMap.put(key, valuesList);
}
}
这是ConcurrentMap
接口具有的原因之一putIfAbsent(K key, V value);
。但这 并不
需要两个操作,所以你可能并不需要围绕它同步。
顺便说一句,我将上面的代码重写为:
synchronized (synchronizedMap) {
// test for a key in the map
List<String> valuesList = synchronizedMap.get(key);
if (valueList == null) {
valuesList = new ArrayList<String>();
// store a value into the map
synchronizedMap.put(key, valuesList);
}
valuesList.add(value);
}
最后,如果地图上的大多数操作synchronized
无论如何都需要位于一个块中,那么您不妨为支付费用,synchronizedMap
而只需HashMap
在synchronized
块中始终使用。
问题内容: 为什么此测试程序会导致? 结果: 问题答案: 您已经正确地指出了必须从同步块中调用。 但是,在您的情况下,由于自动装箱,您在其上同步的对象与您在其上调用的实例不同。实际上,新的,递增的实例仍然被限制在堆栈中,并且其他线程可能不会在调用中被阻塞。 您可以实现自己的可变计数器来执行同步。根据您的应用程序,您可能还会发现AtomicInteger满足您的需求。
问题内容: 我越来越。我提到了这个问题,它解决了我的问题。第一个答案是 我的问题是为什么我们需要在同一个对象广告上进行同步? 据我的理解,当我们说 我们锁定了对象someObject,然后对其调用了wait()。 现在,另一个线程如何才能锁定同一对象以在其上调用notify()? 我想念什么? 问题答案: 为什么也需要锁? 想象一下这种情况: 现在想象一下其他地方没有任何锁定: 乍一看,整个声音总
问题内容: 我读了一些有关闭包的文章,到处都看到了,但是没有明确的解释-每次我被告知要使用它时……: 好的,我看到我们将创建一个新的匿名函数,然后执行它。因此,在此之后,此简单的代码应该可以工作了(并且可以): 我的问题是这里发生了什么魔术?我以为在写的时候: 然后将创建一个新的未命名函数,如函数“”(msg)… 为什么它需要在同一行? 您能给我一些帖子或给我一个解释吗? 问题答案: 将分号放在函
问题内容: 也许我的问题是新手,但是我真的无法理解在什么情况下使用junit? 无论是编写简单的应用程序还是大型应用程序,我都使用语句对其进行测试,这对我来说很容易。 如果仍然需要调用相同的方法,检查它们返回的内容,然后又要为所有内容添加注释,那么为什么要使用JUnit创建测试类,在项目中创建不必要的文件夹呢? 为什么不编写一个类并立即对其进行测试而不创建Test-class? PS。我从未在刚刚
如果有人能提供任何线索,我将不胜感激。我不是一个为了新技术而使用新技术的人。
问题内容: 简介文档中有很多段落专门介绍了和之间的区别,但是实际上,您可以在本地范围内创建对象并将其返回。 为什么要使用一对分配器? 问题答案: 您可以做的事情,您无法做其他任何事情: 建立频道 创建一个预先分配了空间的地图 创建具有预分配空间或len!= cap的切片 证明有一点困难。使它变得更容易的主要事情是创建指向非复合类型的指针。以下两个功能是等效的。简而言之: