Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make my ArrayList Thread-Safe? Another approach to problem in Java?

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!

like image 311
ericso Avatar asked Mar 14 '10 22:03

ericso


People also ask

How do you make an ArrayList thread-safe in Java?

A thread-safe variant of ArrayList in which all mutative operations (e.g., add, set, remove..) are implemented by creating a separate copy of an underlying array. It achieves thread safety by creating a separate copy of the List which is different than vector or other collections used to provide thread-safety.

How can we make thread-safe process in Java?

Using Atomic Variable Using an atomic variable is another way to achieve thread-safety in java. When variables are shared by multiple threads, the atomic variable ensures that threads don't crash into each other.

Is ArrayList multi thread-safe?

Vectors are synchronized. Any method that touches the Vector 's contents is thread safe. ArrayList , on the other hand, is unsynchronized, making them, therefore, not thread safe.


2 Answers

Use Collections.synchronizedList().

Ex:

Collections.synchronizedList(new ArrayList<YourClassNameHere>()) 
like image 107
Amir Afghani Avatar answered Oct 19 '22 08:10

Amir Afghani


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.

like image 42
Reverend Gonzo Avatar answered Oct 19 '22 06:10

Reverend Gonzo