Vraag Java ArrayList - Zijn add () oproepen van de ene thread altijd leesbaar van de andere?


Thread 1: Call list.add()
Thread 1: Exits list.add()
Thread 2: Call list.get(list.size()-1)

Ik heb een scenario waarin ik dat kan garanderen Thread 1 zal de add () aanroep eerder voltooien Thread 2 maak de call get (). Zullen Thread 2 zie altijd de wijzigingen die zijn aangebracht door Thread 1 in dit geval? Of moeten de interne ArrayList-variabelen als vluchtig worden gemarkeerd?

Bewerk: Voor degenen die nieuwsgierig zijn naar waarom ik het kan garanderen. Ik heb een reeks gebeurtenissen van een server die er als volgt uitziet:

Event A1
Event A2
Event A3
Event B

De gebeurtenissen worden opeenvolgend verzonden door een enkele thread. Ik wil een lijst van alle maken A evenementen zodat mijn code er zo uitziet:

List<EventA> eventAList = new ArrayList<>();
connection.addListenerForEventAs(eventAList::add);

connection.waitForEventB();

//Here I am doing operations on the eventAList

15
2018-04-16 10:20


oorsprong


antwoorden:


Allereerst zul je ervoor moeten zorgen dat een gebeurt er eerder relatie bestaat tussen aanroep van add() door thread-1 en een oproep tot get() door draad-2. Voltooiing van de oproep en gebeurt er eerder zijn totaal anders.

Tenzij u dat doet, is uw code niet thread-safe. Waarom?. Thread-1 kan de aanroep beëindigen add() voor thread-2-oproepen get(). Maar wat is de garantie dat Thread-2 het niet zal maken lokale kopie van de lijst (hou het handig) ?. add() methode zorgt niet voor een gebeurt-before. Er is dus geen garantie dat de toegevoegde waarde van de eerste thread zelfs volledig is geschreven en zichtbaar is voor thread-2.

Gebruik CopyOnWriteArrayList of Collections.SynchronizedList() in Meerdradig milieu.


10
2018-04-16 10:34



Gebruik Collections.SynchronizedList () op de list of sleutelwoord gesynchroniseerd met specifieke implementatie voor toevoeging om draadveiligheid te verzekeren,

public synchronized void addItem(Item item) {
    list.add(item);
}

0
2018-04-16 10:37