[英]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.