Ich habe eine ArrayList, mit der ich RaceCar-Objekte speichern möchte, die die Thread-Klasse erweitern, sobald die Ausführung abgeschlossen ist. Eine Klasse namens Race verarbeitet diese ArrayList mithilfe einer Rückrufmethode, die das RaceCar-Objekt nach Abschluss der Ausführung aufruft. Die Rückrufmethode addFinisher (RaceCar-Finisher) fügt das RaceCar-Objekt zur ArrayList hinzu. Dies soll die Reihenfolge angeben, in der die Ausführung der Threads beendet ist.
Ich weiß, dass ArrayList nicht synchronisiert und daher nicht threadsicher ist. Ich habe versucht, die Methode Collections.synchronizedCollection (c Collection) zu verwenden, indem ich eine neue ArrayList übergeben und die zurückgegebene Collection einer ArrayList zugewiesen habe. Dies gibt mir jedoch einen Compilerfehler:
Race.java:41: incompatible types
found : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
Hier ist der relevante Code:
public class Race implements RaceListener {
private Thread[] racers;
private ArrayList finishingOrder;
//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
//Fill array with RaceCar objects
for(int i=0; i<numberOfRaceCars; i++) {
racers[i] = new RaceCar(laps, inputs[i]);
//Add this as a RaceListener to each RaceCar
((RaceCar) racers[i]).addRaceListener(this);
}
//Implement the one method in the RaceListener interface
public void addFinisher(RaceCar finisher) {
finishingOrder.add(finisher);
}
Was ich wissen muss ist, verwende ich einen korrekten Ansatz und wenn nicht, was sollte ich verwenden, um meinen Code threadsicher zu machen? Danke für die Hilfe!
List
Benutzeroberfläche nicht vollständig genug ist, um beim Multithreading sehr nützlich zu sein.)Collections.synchronizedList()
wir ohne hier eine WIRKLICHE Rennbedingung hätten: PAntworten:
Verwenden
Collections.synchronizedList()
.Ex:
quelle
Veränderung
zu
List ist ein Supertyp von ArrayList, daher müssen Sie dies angeben.
Ansonsten scheint das, was Sie tun, in Ordnung zu sein. Eine andere Option ist, dass Sie Vector verwenden können, der synchronisiert ist, aber dies ist wahrscheinlich das, was ich tun würde.
quelle
List
wäre wahrscheinlich nützlicher. OderList<RaceCar>
.//Print out winner System.out.println("The Winner is " + ((RaceCar) finishingOrder.get(0)).toString() + "!");
Es heißt, dass die Methode get (0) nicht gefunden wurde. Gedanken?CopyOnWriteArrayList
Verwenden
CopyOnWriteArrayList
Klasse. Dies ist die thread-sichere Version vonArrayList
.quelle
ConcurrentLinkedQueue
Sie könnten mit dem falschen Ansatz. Nur weil ein Thread, der ein Auto simuliert, vor einem anderen Auto-Simulations-Thread endet, bedeutet dies nicht, dass der erste Thread das simulierte Rennen gewinnen sollte.
Es hängt sehr von Ihrer Anwendung ab, aber es ist möglicherweise besser, einen Thread zu haben, der den Status aller Autos in kleinen Zeitintervallen berechnet, bis das Rennen beendet ist. Wenn Sie mehrere Threads bevorzugen, kann jedes Auto die "simulierte" Zeit aufzeichnen, die für die Beendigung des Rennens benötigt wurde, und den Sieger als den mit der kürzesten Zeit auswählen.
quelle
Sie können auch ein
synchronized
Schlüsselwort für eine solcheaddFinisher
Methode verwendenAuf diese Weise können Sie die ArrayList add-Methode threadsicher verwenden.
quelle
final Object
stattdessen einfach jedes Mal, wenn du aufCollection
irgendeine Weise auf das zugreifst .Wenn Sie eine Ant-Thread-sichere Version des Ant-Collection-Objekts verwenden möchten, verwenden Sie das Paket java.util.concurrent. * . Es gibt fast alle gleichzeitigen Versionen von nicht synchronisierten Sammlungsobjekten. Beispiel: Für ArrayList haben Sie java.util.concurrent.CopyOnWriteArrayList
Sie können Collections.synchronizedCollection (jedes Sammlungsobjekt) ausführen, aber denken Sie an diese klassische Synchronisation. Technik ist teuer und mit Leistungsaufwand verbunden. Das Paket java.util.concurrent. * ist kostengünstiger und verwaltet die Leistung mithilfe von Mechanismen wie
Bevorzugen Sie also etwas aus dem Paket java.util.concurrent. *
quelle
Sie können stattdessen auch als Vektor verwenden, da Vektoren threadsicher sind und Arraylist nicht. Obwohl Vektoren alt sind, können sie Ihren Zweck leicht lösen.
Sie können Ihre Arraylist jedoch wie folgt synchronisieren:
quelle
Sie können von ArrayList zu Vektortyp wechseln, in dem jede Methode synchronisiert wird.
quelle