Pertanyaan Bagaimana cara saya membuat Thread-Aman ArrayList saya? Pendekatan lain untuk masalah di Jawa?


Saya memiliki ArrayList yang ingin saya gunakan untuk menahan objek RaceCar yang memperpanjang kelas Thread segera setelah selesai dieksekusi. Kelas, yang disebut Ras, menangani ArrayList ini menggunakan metode callback yang dipanggil objek RaceCar ketika selesai dieksekusi. Metode callback, addFinisher (Finisher RaceCar), menambahkan objek RaceCar ke ArrayList. Ini seharusnya memberi perintah di mana Threads selesai mengeksekusi.

Saya tahu bahwa ArrayList tidak disinkronkan dan tidak aman. Saya mencoba menggunakan metode Collections.synchronizedCollection (c Collection) dengan meneruskan ArrayList baru dan menugaskan Koleksi yang dikembalikan ke ArrayList. Namun, ini memberi saya kesalahan kompilator:

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

Berikut ini 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? Terima kasih untuk bantuannya!


75
2018-03-14 22:18


asal


Jawaban:


Menggunakan Collections.synchronizedList().

Ex:

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

113
2018-03-14 23:04



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)

Daftar adalah supertipe ArrayList sehingga Anda perlu menentukan itu.

Jika tidak, apa yang Anda lakukan tampaknya baik-baik saja. Pilihan lainnya adalah Anda dapat menggunakan Vector, yang disinkronkan, tetapi ini mungkin apa yang akan saya lakukan.


35
2018-03-14 22:20



CopyOnWriteArrayList

Menggunakan CopyOnWriteArrayList kelas. Ini adalah versi aman dari benang ArrayList.


7
2017-07-21 08:07



Kamu mungkin menggunakan pendekatan yang salah. Hanya karena satu thread yang mensimulasikan sebuah mobil selesai sebelum thread simulasi mobil lain tidak berarti bahwa thread pertama harus memenangkan perlombaan simulasi.

Itu tergantung banyak pada aplikasi Anda, tetapi mungkin lebih baik untuk memiliki satu utas yang menghitung status semua mobil pada interval waktu kecil sampai balapan selesai. Atau, jika Anda lebih suka menggunakan beberapa utas, Anda mungkin memiliki masing-masing mobil merekam waktu "simulasi" yang diperlukan untuk menyelesaikan balapan, dan memilih pemenang sebagai yang memiliki waktu terpendek.


6
2018-03-15 00:33



Anda juga bisa menggunakan synchronized kata kunci untuk addFinisher 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 aman-thread dengan cara ini.


3
2018-03-08 15:08



Anda dapat mengubah dari ArrayList ke jenis Vector, di mana setiap metode disinkronkan.

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

0
2018-03-14 23:13



Kapanpun Anda ingin menggunakan versi semut semut yang aman dari objek koleksi semut, ambillah bantuan java.util.concurrent. * paket. Ini memiliki hampir semua versi konkuren dari objek pengumpulan yang tidak sinkron. misalnya: untuk ArrayList, Anda memiliki java.util.concurrent.CopyOnWriteArrayList

Anda dapat melakukan Collections.synchronizedCollection (objek koleksi apa saja), tetapi ingatlah synchr klasik ini. Teknik ini mahal dan dilengkapi dengan overhead kinerja. java.util.concurrent. * paket lebih murah dan mengelola kinerjanya dengan cara yang lebih baik dengan menggunakan mekanisme seperti

copy-on-write, compare-and-swap, Lock, iterator snapshot, dll.

Jadi, Lebih baik sesuatu dari java.util.concurrent. * Paket


0
2018-03-11 03:02



Anda juga dapat menggunakan sebagai Vektor sebagai gantinya, karena vektor aman dan 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())); 

0
2018-06-11 05:00