2016-12-13 36 views
0

我有一个学生的问题:多核系统中的最终收集线程是否安全?

我想有一个建议和有关问题的能见度在多核一些解释,如果有一个

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

现在我用番石榴ImmutableMap和我敢肯定是没有问题的。但是......

private final Map<ScannerType, ScanExecuter> registry; 

如果我走的,而不是ImmutableMap只是一个最后的映射(不可变的引用而不是内容),可以在任何问题上升?多线程系统中的线程缓存,可视性等问题(即使使用singelton)?

编辑:

所有只要你不修改的内容

没错,我想获得良好的解释。我对Java内存模型还不太了解。

我可以改变地图的内容,只在spring配置类中添加一个新的扫描器。所以应用程序将在任何情况下重新启动。还会有问题吗?

+0

一切都很好,只要你不修改内容,比较http://stackoverflow.com/questions/6457109/java-concurrency-is-final-field-initialized-in-constructor-thread-safe – zapl

回答

2

可以肯定的是,在多线程环境中共享变量不会导致错误,你需要确保:

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

如果您更换一个可变Map(例如一个HashMap)的ImmutableMap所有作品如果线程之间共享后Map没有静音。

请注意,将变量定义为final并不能保证其内容不会改变。 final,对于对象而言,仅意味着该参考不能更改,但可以例如将项目添加,删除或更改为finalMap


(*)注:按@bowmore解释是necessarely保证共享变量的safe publication

安全发布,使所有的出版物都可见之前写入的值

:所观察到的发布对象读者

这是可以做到的210

  • static初始值设定项初始化对象参照。
  • 将参考存储到volatile字段中。
  • 将对其的引用存储到final字段中。
  • 将引用存储到由(​​)锁定正确保护的字段中。
+0

很好的答案,但您还必须确保可变变量安全地发布。 – bowmore

+0

@bowmore我编辑了我的答案,以显示安全地发布可变变量的可能方法 –