Saya memiliki ArrayList yang ingin saya gunakan untuk menampung objek RaceCar yang memperluas kelas Thread segera setelah selesai dijalankan. Sebuah kelas, yang disebut Race, menangani ArrayList ini menggunakan metode callback yang dipanggil oleh objek RaceCar saat selesai dijalankan. Metode callback, addFinisher (RaceCar finisher), menambahkan objek RaceCar ke ArrayList. Ini seharusnya memberi urutan di mana Threads selesai dieksekusi.
Saya tahu bahwa ArrayList tidak disinkronkan dan karenanya tidak aman untuk thread. Saya mencoba menggunakan metode Collections.synchronizedCollection (c Collection) dengan meneruskan ArrayList baru dan menetapkan Collection yang dikembalikan ke ArrayList. Namun, ini memberi saya kesalahan kompiler:
Race.java:41: incompatible types
found : java.util.Collection
required: java.util.ArrayList
finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars));
Berikut adalah kode yang relevan:
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);
}
Yang perlu saya ketahui adalah, apakah saya menggunakan pendekatan yang benar dan jika tidak, apa yang harus saya gunakan untuk membuat kode saya aman untuk thread? Terima kasih untuk bantuannya!
List
antarmuka tidak cukup lengkap untuk menjadi sangat berguna dalam multithreading.)Collections.synchronizedList()
, kami akan memiliki kondisi balapan NYATA di sini: PJawaban:
Gunakan
Collections.synchronizedList()
.Ex:
Collections.synchronizedList(new ArrayList<YourClassNameHere>())
sumber
Perubahan
private ArrayList finishingOrder; //Make an ArrayList to hold RaceCar objects to determine winners finishingOrder = Collections.synchronizedCollection(new ArrayList(numberOfRaceCars)
untuk
private List finishingOrder; //Make an ArrayList to hold RaceCar objects to determine winners finishingOrder = Collections.synchronizedList(new ArrayList(numberOfRaceCars)
List adalah supertipe ArrayList jadi Anda perlu menentukannya.
Jika tidak, apa yang Anda lakukan tampaknya baik-baik saja. Pilihan lainnya adalah Anda dapat menggunakan Vector, yang disinkronkan, tetapi ini mungkin yang akan saya lakukan.
sumber
List
mungkin akan lebih berguna. AtauList<RaceCar>
.//Print out winner System.out.println("The Winner is " + ((RaceCar) finishingOrder.get(0)).toString() + "!");
Dikatakan bahwa metode get (0) tidak ditemukan. Pikiran?CopyOnWriteArrayList
Gunakan
CopyOnWriteArrayList
kelas. Ini adalah versi aman utasArrayList
.sumber
ConcurrentLinkedQueue
Anda mungkin menggunakan pendekatan yang salah. Hanya karena satu utas yang mensimulasikan mobil selesai sebelum utas simulasi mobil lainnya tidak berarti bahwa utas pertama harus memenangkan perlombaan yang disimulasikan.
Ini sangat bergantung pada aplikasi Anda, tetapi mungkin lebih baik memiliki satu utas yang menghitung keadaan semua mobil pada interval waktu kecil hingga balapan selesai. Atau, jika Anda lebih suka menggunakan beberapa utas, Anda mungkin meminta setiap mobil mencatat waktu "simulasi" yang dibutuhkan untuk menyelesaikan balapan, dan memilih pemenang sebagai pemenang dengan waktu tersingkat.
sumber
Anda juga dapat menggunakan
synchronized
kata kunci untukaddFinisher
metode seperti ini//Implement the one method in the RaceListener interface public synchronized void addFinisher(RaceCar finisher) { finishingOrder.add(finisher); }
Jadi Anda bisa menggunakan ArrayList menambahkan metode thread-safe dengan cara ini.
sumber
final Object
setiap kali Anda mengaksesnya denganCollection
cara apa pun.Kapan pun Anda ingin menggunakan versi aman ant thread dari objek ant collection, gunakan bantuan paket java.util.concurrent. * . Ini memiliki hampir semua versi objek koleksi yang tidak tersinkronisasi secara bersamaan. misalnya: untuk ArrayList, Anda memiliki java.util.concurrent.CopyOnWriteArrayList
Anda dapat melakukan Collections.synchronizedCollection (objek koleksi apa pun), tetapi ingat sinkronisasi klasik ini. teknik mahal dan dilengkapi dengan overhead kinerja. java.util.concurrent. * lebih murah dan mengelola kinerja dengan cara yang lebih baik dengan menggunakan mekanisme seperti
Jadi, Lebih suka sesuatu dari paket java.util.concurrent. *
sumber
Anda juga dapat menggunakan sebagai Vektor sebagai gantinya, karena vektor aman untuk utas dan daftar larik tidak. Meskipun vektor sudah tua tetapi mereka dapat menyelesaikan tujuan Anda dengan mudah.
Tetapi Anda dapat membuat Arraylist Anda disinkronkan seperti kode yang diberikan ini:
Collections.synchronizedList(new ArrayList(numberOfRaceCars()));
sumber
Anda dapat mengubah dari ArrayList ke tipe Vector, di mana setiap metode disinkronkan.
private Vector finishingOrder; //Make a Vector to hold RaceCar objects to determine winners finishingOrder = new Vector(numberOfRaceCars);
sumber