Java 以下代码中是否会出现竞态条件
从多个线程调用addId方法时是否会发生竞争编码Java 以下代码中是否会出现竞态条件,java,multithreading,Java,Multithreading,从多个线程调用addId方法时是否会发生竞争编码 private static Map<String , Long> table; static { table = new ConcurrentHashMap<String , Long>(); } public static void addId(String key, Long value){ if(table.containsKey(key)){ table.remove(ke
private static Map<String , Long> table;
static {
table = new ConcurrentHashMap<String , Long>();
}
public static void addId(String key, Long value){
if(table.containsKey(key)){
table.remove(key);
}
table.put(key, value);
}
私有静态映射表;
静止的{
table=新的ConcurrentHashMap();
}
公共静态void addId(字符串键,长值){
if(表containsKey(键)){
表.删除(键);
}
表.put(键、值);
}
没有什么可以阻止另一个线程在containsKey
/remove
和put
之间放置一些值,因此在放置之前检查表是否已经包含键不是真正的“安全”(或者说,没有真正的“意义”)
你为什么不这样做呢
public static void addId(String key, Long value){
table.put(key, value);
}
put
仍将覆盖以前的任何条目
如果不希望多个线程同时执行该方法,请将该方法声明为“已同步”没有任何东西可以阻止另一个线程在
containsKey
/remove
和put
之间放置某个值,因此在放置之前检查表是否已经包含键并不是真正的“安全”(或者更确切地说,没有真正的“意义”)
你为什么不这样做呢
public static void addId(String key, Long value){
table.put(key, value);
}
put
仍将覆盖以前的任何条目
如果不希望多个线程同时执行该方法,请将该方法声明为
synchronized
Yes
(似乎我的答案必须是30个字符或更多)
addId
调用可以给出一个竞争条件:一个线程可以尝试放置一个密钥,另一个线程可以同时删除该密钥(如果是同一个密钥,则可能是一个问题)。在该方法中,还有一些情况可以得到竞争条件(具有各种后果)
如果您有其他方法对表执行其他操作(即从表中读取),则这可能会更加复杂,这将使您的竞争条件比“仅”覆盖的值更糟糕
说到底,你在问什么?你想知道如何避免比赛状态吗?map类的其余部分做什么?是的
(似乎我的答案必须是30个字符或更多)
addId
调用可以给出一个竞争条件:一个线程可以尝试放置一个密钥,另一个线程可以同时删除该密钥(如果是同一个密钥,则可能是一个问题)。在该方法中,还有一些情况可以得到竞争条件(具有各种后果)
如果您有其他方法对表执行其他操作(即从表中读取),则这可能会更加复杂,这将使您的竞争条件比“仅”覆盖的值更糟糕
说到底,你在问什么?你想知道如何避免比赛状态吗?map类的其余部分是做什么的?是的,可能会发生竞争情况
if(table.containsKey(key)){
table.remove(key);
}
table.put(key, value);
另一个线程可以修改containsKey、remove和put之间的表。在执行put()之前,不需要调用remove(),但是-删除containsKey/remove,它将是线程安全的。是的,可能会发生争用情况
if(table.containsKey(key)){
table.remove(key);
}
table.put(key, value);
另一个线程可以修改containsKey、remove和put之间的表。在执行put()之前,不需要调用remove(),但是-删除containsKey/remove,它将是线程安全的。如果您想保证在替换旧值时使用旧值执行某些操作,则争用可能会导致无法处理所有覆盖的键
if(table.containsKey(key)){
Long oldValue = table.remove(key);
}
table.put(key, value);
if (oldValue != null)
importantOperation(oldValue);
编辑:
如果存在旧值,它看起来也会返回旧值,因此检查仍然是不必要的(正如其他人所指定的)。在以下可能涉及赛车的尴尬情况下,检查是必要的:
if(table.containsKey(key)){
Long oldValue = table.remove(key);
value = secretlyAdjustInput(oldValue, value)
}
table.put(key, value);
如果您想保证在替换旧值时使用旧值执行某些操作,那么竞争可能导致无法处理所有被覆盖的键
if(table.containsKey(key)){
Long oldValue = table.remove(key);
}
table.put(key, value);
if (oldValue != null)
importantOperation(oldValue);
编辑:
如果存在旧值,它看起来也会返回旧值,因此检查仍然是不必要的(正如其他人所指定的)。在以下可能涉及赛车的尴尬情况下,检查是必要的:
if(table.containsKey(key)){
Long oldValue = table.remove(key);
value = secretlyAdjustInput(oldValue, value)
}
table.put(key, value);
可以在一行中声明
表
。在一行中声明与在静态类代码中声明相同?是的,但需要一行而不是四行。我还将使表
最终
您可以在一行中声明表
。在一行中声明与在静态类代码中声明相同?是的,但它需要一行而不是四行。我还将使表
成为最终的
类的其余部分只是有一个从表MapI返回值的访问器方法我想知道如何避免竞争条件,如果我的问题a看起来有点模糊,我道歉。这不仅仅是回答,谢谢!类的其余部分只是有一个访问器方法,它从表MapI返回一个值。我想知道如何避免竞争条件,如果我的问题a看起来有点模糊,我道歉。这不仅仅是回答,谢谢!