84 votes

Comment rendre mon Thread-Safe ArrayList? Une autre approche du problème en Java?

J'ai une liste de tableaux que je veux utiliser pour tenir Course des objets qui étendent la classe Thread dès qu'ils ont fini de s'exécuter. Une classe, une Race, qui gère cette liste de tableaux à l'aide d'une méthode de rappel que la voiture de Course de l'objet des appels quand il est fini de l'exécution. La méthode de rappel, addFinisher(voiture de Course de l'unité de finition), ajoute la voiture de Course de l'objet à la liste de tableaux. Ce qui est censé donner l'ordre dans lequel les Threads terminer l'exécution.

Je sais que ArrayList n'est pas synchronisé et donc n'est pas thread-safe. J'ai essayé d'utiliser les Collections.synchronizedCollection(c Collection) méthode en passant par new ArrayList et de l'affectation de la Collection renvoyée à une liste de tableaux. Cependant, cela me donne une erreur de compilation:

Race.java:41: incompatible types
found   : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));

Voici le code correspondant:

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

Ce que j'ai besoin de savoir, c'est que je suis en utilisant une approche correcte et si non, que dois-je utiliser pour faire mon code thread-safe? Merci pour l'aide!

131voto

Amir Afghani Points 17519

35voto

Reverend Gonzo Points 15504

Changement

 private ArrayList finishingOrder;

//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars)
 

à

 private List finishingOrder;

//Make an ArrayList to hold RaceCar objects to determine winners
finishingOrder = Collections.synchronizedList(new ArrayList(numberOfRaceCars)
 

La liste est un supertype de ArrayList, vous devez donc le spécifier.

Sinon, ce que vous faites semble bien se passer. Une autre option est d'utiliser Vector, qui est synchronisé, mais c'est probablement ce que je ferais.

6voto

erickson Points 127945

Vous pourriez être en utilisant la mauvaise approche. Tout simplement parce que un thread qui simule un soin des finitions avant une autre voiture-simulation fil ne signifie pas que le premier thread devrait gagner la simulation de course.

Cela dépend beaucoup de votre application, mais il peut être préférable d'avoir un thread qui calcule l'état de toutes les voitures à petits intervalles de temps jusqu'à ce que la course est terminée. Ou, si vous préférez utiliser plusieurs threads, vous pourriez avoir chaque voiture de record de la "simulé" le temps qu'il a fallu pour terminer la course, et de choisir le gagnant avec le temps le plus court.

4voto

erhun Points 524

Vous pouvez également utiliser synchronized mot clé pour la méthode addFinisher comme ceci

     //Implement the one method in the RaceListener interface
    public synchronized void addFinisher(RaceCar finisher) {
        finishingOrder.add(finisher);
    }
 

Ainsi, vous pouvez utiliser ArrayList add method thread-safe avec cette méthode.

-1voto

darlinton Points 1673

Vous pouvez passer du type ArrayList au type Vector, dans lequel chaque méthode est synchronisée.

 private Vector finishingOrder;
//Make a Vector to hold RaceCar objects to determine winners
finishingOrder = new Vector(numberOfRaceCars);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X