如何使我的 ArrayList 线程安全? Java 中解决问题的另一种方法?

发布于 2024-08-24 22:27:58 字数 1332 浏览 5 评论 0原文

我有一个 ArrayList,我想用它来保存 RaceCar 对象,这些对象在执行完毕后立即扩展 Thread 类。名为 Race 的类使用 RaceCar 对象在完成执行时调用的回调方法来处理此 ArrayList。回调方法 addFinisher(RaceCar finisher) 将 RaceCar 对象添加到 ArrayList 中。这应该给出线程完成执行的顺序。

我知道 ArrayList 不是同步的,因此不是线程安全的。我尝试通过传入新的 ArrayList 并将返回的 Collection 分配给 ArrayList 来使用 Collections.synchronizedCollection(c Collection) 方法。但是,这给了我一个编译器错误:

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

我需要知道的是,我使用的方法是否正确,如果不正确,我应该使用什么来使我的代码线程安全?感谢您的帮助!

I have an ArrayList that I want to use to hold RaceCar objects that extend the Thread class as soon as they are finished executing. A class, called Race, handles this ArrayList using a callback method that the RaceCar object calls when it is finished executing. The callback method, addFinisher(RaceCar finisher), adds the RaceCar object to the ArrayList. This is supposed to give the order in which the Threads finish executing.

I know that ArrayList isn't synchronized and thus isn't thread-safe. I tried using the Collections.synchronizedCollection(c Collection) method by passing in a new ArrayList and assigning the returned Collection to an ArrayList. However, this gives me a compiler error:

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

Here is the relevant 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);
    }

What I need to know is, am I using a correct approach and if not, what should I use to make my code thread-safe? Thanks for the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

樱娆 2024-08-31 22:27:58

使用 Collections.synchronizedList()

前任:

Collections.synchronizedList(new ArrayList<YourClassNameHere>())

Use Collections.synchronizedList().

Ex:

Collections.synchronizedList(new ArrayList<YourClassNameHere>())
痞味浪人 2024-08-31 22:27:58

更改

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 的超类型,因此您需要指定它。

否则,你正在做的事情看起来不错。另一种选择是你可以使用 Vector,它是同步的,但这可能就是我会做的。

Change

private ArrayList finishingOrder;

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

to

private List finishingOrder;

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

List is a supertype of ArrayList so you need to specify that.

Otherwise, what you're doing seems fine. Other option is you can use Vector, which is synchronized, but this is probably what I would do.

北城半夏 2024-08-31 22:27:58

CopyOnWriteArrayList

使用CopyOnWriteArrayList 类。这是 ArrayList

CopyOnWriteArrayList

Use CopyOnWriteArrayList class. This is the thread safe version of ArrayList.

夏九 2024-08-31 22:27:58

您还可以在 addFinisher 方法中使用 synchronized 关键字,

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

这样您就可以通过这种方式使用 ArrayList add 方法线程安全。

You can also use synchronized keyword for addFinisher method like this

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

So you can use ArrayList add method thread-safe with this way.

债姬 2024-08-31 22:27:58

可能使用了错误的方法。仅仅因为模拟汽车的一个线程在另一个汽车模拟线程之前完成并不意味着第一个线程应该赢得模拟比赛。

这在很大程度上取决于您的应用程序,但最好有一个线程以较小的时间间隔计算所有汽车的状态,直到比赛完成。或者,如果您更喜欢使用多线程,您可以让每辆车记录完成比赛所需的“模拟”时间,并选择时间最短的获胜者。

You might be using the wrong approach. Just because one thread that simulates a car finishes before another car-simulation thread doesn't mean that the first thread should win the simulated race.

It depends a lot on your application, but it might be better to have one thread that computes the state of all cars at small time intervals until the race is complete. Or, if you prefer to use multiple threads, you might have each car record the "simulated" time it took to complete the race, and choose the winner as the one with shortest time.

半衬遮猫 2024-08-31 22:27:58

每当你想使用 ant 线程安全版本的 ant 集合对象时,请借助 java.util.concurrent.* 包。
它几乎拥有所有并发版本的不同步集合对象。例如:对于ArrayList,您有java.util.concurrent.CopyOnWriteArrayList

您可以执行Collections.synchronizedCollection(任何集合对象),但请记住这个经典的synchr。该技术非常昂贵并且会带来性能开销。
java.util.concurrent.* 包成本较低,并且通过使用类似机制以更好的方式管理性能

写入时复制、比较和交换、锁定、快照迭代器等

所以,更喜欢 java.util.concurrent.* 包中的东西

Whenever you want to use ant thread safe version of ant collection object,take help of java.util.concurrent.* package.
It has almost all concurrent version of unsynchronized collection objects. eg: for ArrayList, you have java.util.concurrent.CopyOnWriteArrayList

You can do Collections.synchronizedCollection(any collection object),but remember this classical synchr. technique is expensive and comes with performence overhead.
java.util.concurrent.* package is less expensive and manage the performance in better way by using mechanisms like

copy-on-write,compare-and-swap,Lock,snapshot iterators,etc.

So,Prefer something from java.util.concurrent.* package

漆黑的白昼 2024-08-31 22:27:58

您也可以使用 as Vector 来代替,因为向量是线程安全的,而 arraylist 不是。
虽然向量很旧,但它们可以轻松解决您的目的。

但是您可以像下面的代码一样使您的 Arraylist 同步:

Collections.synchronizedList(new ArrayList(numberOfRaceCars())); 

You can also use as Vector instead, as vectors are thread safe and arraylist are not.
Though vectors are old but they can solve your purpose easily.

But you can make your Arraylist synchronized like code given this:

Collections.synchronizedList(new ArrayList(numberOfRaceCars())); 
-残月青衣踏尘吟 2024-08-31 22:27:58

您可以从 ArrayList 更改为 Vector 类型,其中每个方法都是同步的。

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

You can change from ArrayList to Vector type, in which every method is synchronized.

private Vector finishingOrder;
//Make a Vector to hold RaceCar objects to determine winners
finishingOrder = new Vector(numberOfRaceCars);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文