2017-01-15 5 views
2

私はハッシュマップと複合オブジェクトを初期化し、メインスレッドで更新しました。エグゼキュータサービスの完全初期化の保証

Map<String,String> map = new HashMap<>(); 
map.put("key1","val1"); 
map.put("key2","val2"); 
map.put("key3","va3"); 
map.put("key4","val4"); 

ComplexObject c1 = new ComplexObject(); 
c1.setPropert1(prop1);c1.setProperty2(map); 

ExecutorService executorService = Executors.newFixedThreadPool(10); 

executorService.submit(()->{ 
    Map<String,String> m = c1.getProperty2(); 
    String val = m.get("key1"); //1 
    //do something 
}); 

excutorサービスに提出されたスレッドは、1行目にVAL1としてのvalを見るためにguranteedか、メインスレッドでHashMapを初期化することができますが、まだ完全に起因するプールに提出並べ替え命令およびスレッドにinitialsedされていませんがNULLとしてのvalを得ることができます?

私はプールに提出してくださいスレッドが複雑なオブジェクトを取得するために何をすべきでは完全にintialised C1およびそのすべてのプロパティは、完全に彼らはハッシュマップまたはさらに複雑なオブジェクトであるかどうかを設定されています。

答えて

4

ExecutorServiceにドキュメントを参照してください:

メモリー整合性効果:ExecutorServicehappen-before前にRunnableまたはCallableタスクの提出にスレッド内のアクションの順番に起こるそのタスクによって取られた措置、 -より前に結果はFuture.get()で検索されます。

だから、はい、mapc1は完全に同じスレッドに後で提出したタスクに初期化されます。

+0

なぜ私たちはすべてのプロパティをfinalまたはinitialisationが同期ブロックで実行されるように強制するのですか?私の主張は、主スレッドの命令を並べ替えることによって、まだc1のコンストラクタをコンパイルし、m1に値を入れ、executor.submitを(命令の並べ替えのために)呼び出すアクションをまだ実行していないためです。今度はスレッドがキーをnullとして取得します。メインスレッドがc1.getProperty2()。get( "key1")にアクセスする必要があるときに、メインスレッドでアクションがまだ実行されていないためです。 – user1846749

+0

@ user1846749あなたの懸念は、スレッド間の通常の共有に関して完全に有効です。しかし、同期、「volatile」変数へのアクセス、スレッドの開始など、可視性の問題を防ぐために保証されているアクションがあります。 'ExecutorService'はこれらのメカニズムを使用して、新しいタスクの適切な可視性を確保します。詳細については、上の2番目のリンクを参照してください。 – shmosel

+0

したがって、エグゼクティブサービスの代わりに私がやったとすれば。 スレッドt =新しいMyThread(ComplexObjectc2); t.start(); --- スレッドtで - アクセスcomplextobject2 - 私がnullとしてcomplextobject2.getpropert2を()得ることができます? – user1846749

関連する問題