我如何使我的ArrayList线程安全? 在Java中的另一个问题的方法?
我有一个ArrayList,我想用它来保存完成执行后立即扩展Thread类的RaceCar对象。 一个名为Race的类使用RaceCar对象在完成执行时调用的callback方法来处理这个ArrayList。 callback方法addFinisher(RaceCar finisher)将RaceCar对象添加到ArrayList。 这应该给出线程完成执行的顺序。
我知道ArrayList不同步,因此不是线程安全的。 我尝试使用Collections.synchronizedCollection(c Collection)方法,方法是传入一个新的ArrayList,并将返回的Collection分配给一个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>())
更改
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)
List是ArrayList的超types,所以你需要指定它。
否则,你在做什么似乎很好。 其他选项是你可以使用Vector,这是同步的,但这可能是我会做的。
CopyOnWriteArrayList
使用CopyOnWriteArrayList
类。 这是ArrayList
的线程安全版本。
你可能会使用错误的方法。 仅仅因为一个模拟汽车的线程在另一个汽车模拟线程之前完成并不意味着第一个线程应该赢得模拟的比赛。
这在很大程度上取决于你的应用程序,但是最好有一个线程能够以较小的时间间隔计算所有赛车的状态,直到比赛结束。 或者,如果您更喜欢使用多个线程,则可以让每辆赛车logging完成比赛所需的“模拟”时间,并以最短的时间选出胜出者。
您也可以使用像这样的addFinisher
方法的synchronized
关键字
//Implement the one method in the RaceListener interface public synchronized void addFinisher(RaceCar finisher) { finishingOrder.add(finisher); }
所以你可以用这种方式使用ArrayList的add方法线程安全。
您可以从ArrayList更改为Vectortypes,其中每个方法都是同步的。
private Vector finishingOrder; //Make a Vector to hold RaceCar objects to determine winners finishingOrder = new Vector(numberOfRaceCars);
每当你想使用ant线程安全版本的ant收集对象时,请接受java.util.concurrent。*包的帮助。 它具有几乎所有并行版本的不同步集合对象。 例如:对于ArrayList,您有java.util.concurrent.CopyOnWriteArrayList
你可以做Collections.synchronizedCollection(任何集合对象),但记住这个古典同步。 技术是昂贵的,并伴随着性能开销。 java.util.concurrent。*包比较便宜,并且通过使用类似的机制以更好的方式pipe理性能
写入时复制,比较和交换,locking,快照迭代器等。
所以,首选java.util.concurrent。*包