简体   繁体   English

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

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

i have a student question: 我有一个学生问题:

i would like to have an advice and some explanation about visibility problem in multicore if there is one . 如果有的话,我想就多核的可见性问题提出建议和一些解释。

I use Registry pattern in my SpringBoot Application to map different scanners instances to their names. 我在SpringBoot应用程序中使用注册表模式将不同的扫描仪实例映射到它们的名称。

Configuration: 组态:

@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);
}

Registry: 注册表:

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();
    }

Right now i am using ImmutableMap from Guava and i am pretty sure there is no problem. 现在我正在使用Guava的ImmutableMap,我很确定没有问题。 But... 但...

private final Map<ScannerType, ScanExecuter> registry;

If i take instead of ImmutableMap just a final map (immutable reference but not content), could any problem rise? 如果我只使用最终地图(不可变参考,但不包含内容)代替ImmutableMap,会出现任何问题吗? Any problem with thread caches, visibility et cetera in multicore systems (even with the usage of singeltons)? 多线程系统中的线程缓存,可见性等存在任何问题(即使使用singeltons)?

EDITED: 编辑:

All good as long as you don't modify the content 只要您不修改内容,一切都很好

Exactly that i would like to get explained. 正是我想得到解释。 I am not so good with java memory model yet. 我对Java内存模型还不太满意。

I can change the content of map, only in spring configuration class adding a new scanner. 我只能在spring配置类中添加新的扫描仪,才能更改map的内容。 So the application will restart in any case. 因此,无论如何该应用程序都将重新启动。 Can there still be a problem? 还会有问题吗?

To be sure that a variable shared in a multithread environment doesn't cause errors you need to ensure that: 为确保在多线程环境中共享的变量不会导致错误,您需要确保:

  • The variable is immutable or 变量是不可变的,或者
  • The variable is mutable, but the access to that variable is synchronized or 该变量是可变的,但是对该变量的访问是同步的或
  • The variable is mutable, but you don't change its value after creating it (*). 该变量是可变的,但是在创建变量(*)后不要更改其值。

If you replace an ImmutableMap with a mutable Map (for example an HashMap ) all works if that Map is not muted after it is shared between threads. 如果将ImmutableMap替换为可变的Map (例如HashMap ),则在线程之间共享该Map之后不对其进行静音的情况下,所有工作都可以进行。

Note that defining a variable as final doesn't ensure that its content never change. 请注意,将变量定义为final并不能确保其内容永远不变。 final , for objects, means only that the reference can't be changed, but it is possible for example to add, remove or change items to a final Map . 对于对象来说, final意味着仅不能更改引用,但是例如可以向final Map添加,删除或更改项目。


(*) Note: as explained by @bowmore it is necessarely to guarantee a safe publication of the shared variable: (*)注意:如@bowmore所解释,有必要保证共享变量的安全发布

Safe publication makes all the values written before the publication visible to all readers that observed the published object 安全发布使观察发布对象的所有读者都可以看到发布之前写的所有值

This can be done with: 这可以通过以下方式完成:

  • Initializing an object reference from a static initializer. static初始化程序初始化对象引用。
  • Storing a reference to it into a volatile field. 将对它的引用存储到volatile字段中。
  • Storing a reference to it into a final field. 将对它的引用存储到final字段中。
  • Storing a reference to it into a field that is properly guarded by a ( synchronized ) lock. 将对它的引用存储到由( synchronized )锁适当保护的字段中。

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

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