[英]Is this class thread-safe?
此类是单身人士。 我不太擅长线程安全。 该类是线程安全的吗? 一些方法被省略,但是它们仅在一个线程中使用。 但是,这里列出的方法将同时从多个线程访问。
public class TermsDto {
private final static MapSplitter mapSplitter = Splitter
.on(',').trimResults().omitEmptyStrings()
.withKeyValueSeparator(":");
private volatile double factorForOthers = 4;
private volatile Map<String, Double> factorForTermName =
new HashMap<String, Double>();
public void setFactorForOthers(double factorForOthers) {
this.factorForOthers = factorForOthers;
}
public void setFactorForTermNameMapping(String mapping) {
HashMap<String, Double> tempFactorForTermName =
new HashMap<String, Double>();
for (Map.Entry<String, String> entry :
mapSplitter.split(mapping).entrySet()) {
double factor = Double.parseDouble(entry.getValue());
tempFactorForTermName.put(entry.getKey(), factor);
}
factorForTermName = tempFactorForTermName;
}
}
在显示的所有代码中,只有以下几部分是相关的:
private volatile double factorForOthers = 4;
private volatile Map<String, Double> factorForTermName =
new HashMap<String, Double>();
public void setFactorForOthers(double factorForOthers) {
this.factorForOthers = factorForOthers;
}
public void setFactorForTermNameMapping(String mapping) {
HashMap<String, Double> tempFactorForTermName =
new HashMap<String, Double>();
for (Map.Entry<String, String> entry :
mapSplitter.split(mapping).entrySet()) {
double factor = Double.parseDouble(entry.getValue());
tempFactorForTermName.put(entry.getKey(), factor);
}
factorForTermName = tempFactorForTermName;
}
rank
和rankSubtractionByCountsPerDay
方法是纯函数,因此按定义是线程安全的。 现在,由于您的setFactorForTermNameMapping
不依赖于任何共享状态,而是仅写入volatile变量,因此其操作是原子的。
如果未显示的方法仅读取映射,并且经过精心编写只能访问一次 factorForTermName
,则整个类可能是线程安全的。
如所写,我认为该类是线程安全的。
但是,它是线程安全的主要原因是变量factorForOthers
和factorForTermName
是只写的 。 由于没有代码读取它们,因此线程不可能看到它们处于不一致状态。
当然,这使该类毫无用处,并且使我们得出明显的结论,那就是这不是您担心的真正代码。
如果factorForOthers
被吸气剂暴露(例如),它将仍然是线程安全的。 ( double
是原始数,参考变量是volatile
如果暴露了factorForTermName
,那么肯定存在应用程序暂时不是线程安全的风险 。 这取决于是否可以更新暴露的地图。 如果可以,则存在严重的线程安全问题。 有两种方法可以减轻这种情况:
您可以使用Collections.unModifiableMap()
更改setFactorForTermNameMapping
以包装HashMap
。 如果您的意图是地图应该是只读的,那么这是最好的解决方案。
您可以使用ConcurrentHashMap
代替HashMap
。
不。这不是thread
安全的。 HashMap
本身不是线程安全的。 您可以将Synchronized
方法与HashMap
一起使用,以在HashTable
实现相同的thread
安全功能
假设没有其他方法修改factorForTermName映射,则该类是线程安全的。
否。方法setFactorForTermNameMapping()遍历一个数据结构,该数据结构本身对于遍历可能不是线程安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.