2016-12-13 75 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我編輯了我的答案,以顯示安全地發佈可變變量的可能方法 –