2017-01-15 3 views
2

Ich habe eine hashmap und ein komplexes Objekt initialisiert und im Haupt-Thread aktualisiert.Executor Service volle Initialisierung Garantie

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

ist Thread in excutor Dienst, guranteed val als val1 auf Linie sehen 1 oder es kann HashMap in Hauptthread initialisiert werden ist noch nicht vollständig aufgrund Anweisung initialsed Neuordnen und im Pool eingereichten Thread kann val bekommen als null .?

Was muss ich tun, um sicherzustellen, dass Threads, die im Pool übergeben werden, das komplexe Objekt c1 vollständig initialisiert bekommen und alle seine Eigenschaften vollständig gesetzt sind, egal ob es sich um hashmap oder um weitere komplexe Objekte handelt.

Antwort

4

Lesen Sie die Dokumentation zu ExecutorService:

Speicherkonsistenz Effekte: Aktionen in einem Thread vor der Vorlage einer Runnable oder Callable Aufgabe eine ExecutorServicehappen-before jegliche von dieser Aufgabe ergriffenen Maßnahmen, die wiederum passieren -vor wird das Ergebnis über Future.get() abgerufen.

Also, ja, map und c1 werden vollständig auf die später im selben Thread eingereichten Aufgabe initialisiert werden.

+0

Warum werden wir gezwungen, alle unsere Eigenschaften als Final oder Initialisierung in synchronisierten Block zu machen? Mein Punkt ist, wenn sagen, dass aufgrund der Anweisung Neuordnung Hauptthread noch Aktion des Compilierens von c1 Konstruktor und Putting Werte in M1 und zuvor genannt executor.submit (wegen Instruktion Neuordnung durchgeführt). Jetzt wird get Schlüssel als null erhalten. Da die Aktion im Hauptthread noch nicht erledigt ist, wird sie im Hauptthread ausgeführt, wenn der Hauptthread auf c1.getProperty2() zugreifen muss. get ("key1")? – user1846749

+0

@ user1846749 Ihre Bedenken sind in Bezug auf die normale Freigabe zwischen Threads absolut gültig. Aber es gibt bestimmte Aktionen, die garantiert Sichtbarkeitsprobleme verhindern, wie Synchronisation, Zugriff auf eine "volatile" Variable oder den Start eines Threads. 'ExecutorService' verwendet diese Mechanismen, um eine korrekte Sichtbarkeit für neue Aufgaben zu gewährleisten. Siehe den zweiten Link oben für weitere Details. – shmosel

+0

Also wenn ich statt Executor Service sage hätte ich getan. Thread t = neu MyThread (ComplexObjectc2); t.start(); --- Im Thread t - Zugriff complextobject2 - Ich könnte complextobject2.getpropert2() als null ?? – user1846749

Verwandte Themen