Apa cara untuk menunggu semua proses berulir selesai? Misalnya, saya punya:
public class DoSomethingInAThread implements Runnable{
public static void main(String[] args) {
for (int n=0; n<1000; n++) {
Thread t = new Thread(new DoSomethingInAThread());
t.start();
}
// wait for all threads' run() methods to complete before continuing
}
public void run() {
// do something here
}
}
Bagaimana cara mengubah ini sehingga main()
metode berhenti di komentar sampai semua run()
metode utas keluar? Terima kasih!
java
multithreading
parallel-processing
wait
DivideByHero
sumber
sumber
Salah satu cara untuk membuat
List
dariThread
s, membuat dan meluncurkan setiap thread, sambil menambahkan ke dalam daftar. Setelah semuanya diluncurkan, putar kembali daftar dan panggiljoin()
masing-masing. Tidak peduli apa urutan utas selesai dieksekusi, yang perlu Anda ketahui adalah bahwa pada saat loop kedua selesai dieksekusi, setiap utas akan selesai.Pendekatan yang lebih baik adalah dengan menggunakan ExecutorService dan metode terkaitnya:
Menggunakan ExecutorService (dan semua hal baru dari utilitas konkurensi Java 5 ) sangat fleksibel, dan contoh di atas bahkan hampir tidak menyentuh permukaan.
sumber
sumber
alih-alih
join()
, yang merupakan API lama, Anda bisa menggunakan CountDownLatch . Saya telah mengubah kode Anda seperti di bawah ini untuk memenuhi kebutuhan Anda.Penjelasan :
CountDownLatch
telah diinisialisasi dengan hitungan 1000 sesuai kebutuhan Anda.Setiap thread pekerja
DoSomethingInAThread
akan mengurangiCountDownLatch
, yang telah diteruskan dalam konstruktor.Utas utama
CountDownLatchDemo
await()
sampai hitungannya menjadi nol. Setelah hitungan menjadi nol, Anda akan mendapatkan baris di bawah ini dalam keluaran.Info lebih lanjut dari halaman dokumentasi oracle
Lihat pertanyaan SE terkait untuk opsi lain:
tunggu sampai semua thread menyelesaikan pekerjaannya di java
sumber
Hindari kelas Thread sama sekali dan sebagai gantinya gunakan abstraksi yang lebih tinggi yang disediakan di java.util.concurrent
Kelas ExecutorService menyediakan metode invokeAll yang tampaknya melakukan apa yang Anda inginkan.
sumber
Pertimbangkan untuk menggunakan
java.util.concurrent.CountDownLatch
. Contoh di javadocssumber
Seperti yang disarankan Martin K
java.util.concurrent.CountDownLatch
tampaknya menjadi solusi yang lebih baik untuk ini. Hanya menambahkan contoh yang samasumber
Bergantung pada kebutuhan Anda, Anda mungkin juga ingin memeriksa kelas CountDownLatch dan CyclicBarrier dalam paket java.util.concurrent. Mereka dapat berguna jika Anda ingin agar thread Anda menunggu satu sama lain, atau jika Anda ingin kontrol yang lebih cermat atas cara thread Anda dieksekusi (misalnya, menunggu dalam eksekusi internalnya untuk thread lain untuk menyetel beberapa status). Anda juga dapat menggunakan CountDownLatch untuk memberi sinyal semua utas Anda untuk memulai pada waktu yang sama, daripada memulainya satu per satu saat Anda mengulang melalui loop Anda. Dokumen API standar memiliki contohnya, ditambah menggunakan CountDownLatch lain untuk menunggu semua utas menyelesaikan eksekusinya.
sumber
Jika Anda membuat daftar utas, Anda dapat mengulanginya dan .join () terhadap masing-masing utas, dan putaran Anda akan selesai ketika semua utas memilikinya. Saya belum mencobanya.
http://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join ()
sumber
Buat objek utas di dalam loop for pertama.
Dan kemudian apa yang dikatakan semua orang di sini.
sumber
Anda dapat melakukannya dengan Object "ThreadGroup" dan parameternya activeCount :
sumber
Sebagai alternatif dari CountDownLatch, Anda juga dapat menggunakan CyclicBarrier mis
Untuk menggunakan CyclicBarrier dalam hal ini barrier.await () harus menjadi pernyataan terakhir yaitu saat utas Anda selesai dengan tugasnya. CyclicBarrier dapat digunakan lagi dengan metode reset (). Mengutip javadocs:
CyclicBarrier mendukung perintah Runnable opsional yang dijalankan satu kali per titik penghalang, setelah utas terakhir dalam pesta tiba, tetapi sebelum utas apa pun dilepaskan. Tindakan penghalang ini berguna untuk memperbarui keadaan bersama sebelum salah satu pihak melanjutkan.
sumber
Itu
join()
tidak membantu saya. lihat contoh ini di Kotlin:Hasil:
Sekarang izinkan saya menggunakan
join()
for utas:Dan hasilnya:
Seperti yang jelas saat kami menggunakan
join
:Solusi kami untuk mencegah pemblokiran utas lain adalah membuat ArrayList:
Sekarang ketika kita ingin memulai utas baru, kita paling menambahkannya ke ArrayList:
The
addThreadToArray
Fungsi:The
startNewThread
funstion:Periksa penyelesaian utas seperti di bawah ini di mana pun itu diperlukan:
sumber