繁体   English   中英

该类是线程安全的吗?

[英]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;
}

rankrankSubtractionByCountsPerDay方法是纯函数,因此按定义是线程安全的。 现在,由于您的setFactorForTermNameMapping不依赖于任何共享状态,而是仅写入volatile变量,因此其操作是原子的。

如果未显示的方法仅读取映射,并且经过精心编写只能访问一次 factorForTermName ,则整个类可能是线程安全的。

如所写,我认为该类是线程安全的。

但是,它是线程安全的主要原因是变量factorForOthersfactorForTermName只写的 由于没有代码读取它们,因此线程不可能看到它们处于不一致状态。

当然,这使该类毫无用处,并且使我们得出明显的结论,那就是这不是您担心的真正代码。


如果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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM