У меня есть ArrayList, который я хочу использовать для содержания объектов RaceCar, которые расширяют класс Потока, как только они закончены, выполнившись. Класс, названный Гонкой, обрабатывает этот ArrayList с помощью метода обратного вызова, что вызовы объектов RaceCar, когда это закончено, выполнившись. Метод обратного вызова, addFinisher (Финишер RaceCar), добавляет объект RaceCar к ArrayList. Это, как предполагается, дает распоряжение, в котором Потоки заканчивают выполняться.
Я знаю, что ArrayList не синхронизируется и таким образом не ориентирован на многопотоковое исполнение. Я пытался использовать Collections.synchronizedCollection (c Набор) метод путем передачи в новом ArrayList и присвоения возвращенного Набора ArrayList. Однако это дает мне ошибку компилятора:
Race.java:41: incompatible types
found : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
Вот соответствующие нормы:
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);
}
То, что я должен знать, я использую корректный подход и в противном случае что я должен использовать для создания моего кода ориентированным на многопотоковое исполнение? Спасибо за справку!
Используйте Collections.synchronizedList ()
.
Пример:
Collections.synchronizedList(new ArrayList<YourClassNameHere>())
Вы возможно используете неправильный подход. Если один поток, имитирующий автомобиль, финиширует раньше другого потока, имитирующего автомобиль, это не значит, что первый поток должен выиграть имитируемую гонку.
Это во многом зависит от вашего приложения, но, возможно, лучше иметь один поток, который вычисляет состояние всех автомобилей через небольшие промежутки времени до завершения гонки. Или, если вы предпочитаете использовать несколько потоков, вы можете заставить каждый автомобиль записывать "симулированное" время, которое потребовалось для завершения гонки, и выбрать победителя, который затратил наименьшее время.
Вы можете перейти от типа ArrayList к типу Vector, в котором каждый метод синхронизирован.
private Vector finishingOrder;
//Make a Vector to hold RaceCar objects to determine winners
finishingOrder = new Vector(numberOfRaceCars);
Изменить
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)
Список является супертипом ArrayList, поэтому вам нужно указать это.
В остальном то, что вы делаете, кажется нормальным. Другой вариант - вы можете использовать вектор, который синхронизируется, но, вероятно, это то, что я бы сделал.