繁体   English   中英

最终收集线程在多核系统中安全吗?

[英]Is a final collection thread safe in multicore system?

我有一个学生问题:

如果有的话,我想就多核的可见性问题提出建议和一些解释。

我在SpringBoot应用程序中使用注册表模式将不同的扫描仪实例映射到它们的名称。

组态:

@Bean
public WebScannerExecutor webScannerExecutor(final WebScannerClientProcessor webScannerClientProcessor) {
    return new WebScannerExecutor(webScannerClientProcessor);
}

@Bean
public TLSScannerExecutor tlsScannerExecutor(final @Value("${tls.scanner.path}") String path, final BashProcessor bashProcessor) {
    return new TLSScannerExecutor(path, bashProcessor);
}

@Bean
public ScanExecuterRegistry executerRegistry(final WebScannerExecutor webScannerExecutor, final TLSScannerExecutor tlsScannerExecutor) {
    final ScanExecuter[] arr = new ScanExecuter[] {webScannerExecutor, tlsScannerExecutor};
    return new ScanExecuterRegistry(arr);
}

注册表:

public class ScanExecuterRegistry {

private final ImmutableMap<ScannerType, ScanExecuter> registry;

 public ScanExecuterRegistry(final ScanExecuter... executors) {
        this.registry = ImmutableMap.<ScannerType, ScanExecuter> builder().putAll(Arrays.asList(executors).stream().collect(Collectors.toMap(ScanExecuter::getType, e -> e))).build();
    }

现在我正在使用Guava的ImmutableMap,我很确定没有问题。 但...

private final Map<ScannerType, ScanExecuter> registry;

如果我只使用最终地图(不可变参考,但不包含内容)代替ImmutableMap,会出现任何问题吗? 多线程系统中的线程缓存,可见性等存在任何问题(即使使用singeltons)?

编辑:

只要您不修改内容,一切都很好

正是我想得到解释。 我对Java内存模型还不太满意。

我只能在spring配置类中添加新的扫描仪,才能更改map的内容。 因此,无论如何该应用程序都将重新启动。 还会有问题吗?

为确保在多线程环境中共享的变量不会导致错误,您需要确保:

  • 变量是不可变的,或者
  • 该变量是可变的,但是对该变量的访问是同步的或
  • 该变量是可变的,但是在创建变量(*)后不要更改其值。

如果将ImmutableMap替换为可变的Map (例如HashMap ),则在线程之间共享该Map之后不对其进行静音的情况下,所有工作都可以进行。

请注意,将变量定义为final并不能确保其内容永远不变。 对于对象来说, final意味着仅不能更改引用,但是例如可以向final Map添加,删除或更改项目。


(*)注意:如@bowmore所解释,有必要保证共享变量的安全发布

安全发布使观察发布对象的所有读者都可以看到发布之前写的所有值

这可以通过以下方式完成:

  • static初始化程序初始化对象引用。
  • 将对它的引用存储到volatile字段中。
  • 将对它的引用存储到final字段中。
  • 将对它的引用存储到由( synchronized )锁适当保护的字段中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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