Saya membaca melalui java.util.concurrent API , dan menemukan itu
CountDownLatch
: Bantuan sinkronisasi yang memungkinkan satu atau beberapa utas menunggu hingga serangkaian operasi dilakukan pada utas lainnya selesai.CyclicBarrier
: Alat bantu sinkronisasi yang memungkinkan satu set utas semua menunggu satu sama lain untuk mencapai titik penghalang umum.
Bagi saya keduanya tampak sama, tetapi saya yakin ada lebih dari itu.
Misalnya, dalam CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier
.
Apakah ada perbedaan lain di antara keduanya?
Di use cases
mana seseorang ingin mereset nilai hitung mundur?
java
concurrency
countdownlatch
cyclicbarrier
pelamun
sumber
sumber
Jawaban:
Satu perbedaan utama adalah bahwa CyclicBarrier mengambil tugas Runnable (opsional) yang dijalankan setelah kondisi penghalang umum terpenuhi.
Ini juga memungkinkan Anda untuk mendapatkan jumlah klien yang menunggu di penghalang dan jumlah yang dibutuhkan untuk memicu penghalang. Setelah dipicu penghalang diatur ulang dan dapat digunakan lagi.
Untuk kasus penggunaan sederhana - layanan mulai dll ... CountdownLatch baik-baik saja. CyclicBarrier berguna untuk tugas koordinasi yang lebih kompleks. Contoh dari hal seperti itu adalah komputasi paralel - di mana banyak subtugas terlibat dalam perhitungan - semacam MapReduce seperti .
sumber
Ada perbedaan lain.
Saat menggunakan a
CyclicBarrier
, asumsinya adalah Anda menentukan jumlah utas yang memicu penghalang. Jika Anda menentukan 5, Anda harus memiliki setidaknya 5 utas untuk dihubungiawait()
.Saat menggunakan a
CountDownLatch
, Anda menentukan jumlah panggilancountDown()
yang akan menghasilkan semua utas tunggu yang dirilis. Ini berarti bahwa Anda dapat menggunakanCountDownLatch
dengan hanya satu utas."Mengapa kamu melakukan itu?", Kamu mungkin berkata. Bayangkan Anda menggunakan API misterius yang dikodekan oleh orang lain yang melakukan panggilan balik. Anda ingin salah satu utas Anda menunggu hingga panggilan balik tertentu telah dipanggil beberapa kali. Anda tidak tahu utas mana yang akan dipanggil kembali. Dalam hal ini, a
CountDownLatch
sempurna, sedangkan saya tidak bisa memikirkan cara untuk mengimplementasikan ini menggunakanCyclicBarrier
(sebenarnya, saya bisa, tetapi ini melibatkan waktu tunggu ... yuck!).Saya hanya berharap itu
CountDownLatch
bisa diatur ulang!sumber
CountDownLatch
dapat direset - solusi yang saya gunakan untuk menerapkan pemberitahuan tunggu kasar hanya untukCountDownLatch
segera memulai segera ketika blok kode yang dilindungi dimasukkan (ketika kait mencapai nol). Ini tidak berlaku dalam semua keadaan / cakupan tentu saja, tetapi saya pikir perlu dicatat bahwa ini adalah opsi dalam situasi goldilocks.Java Concurrency in Practice
- mengatakan hal yang sama:Latches are for waiting for events; barriers are for waiting for other threads.
. Poin utama dan esensial untuk memahami perbedaan antara keduanya.Satu hal yang belum ada yang disebutkan adalah bahwa,
CyclicBarrier
jika, sebuah utas memiliki masalah (batas waktu, terputus ...), semua yang lain yang telah mencapaiawait()
dapatkan pengecualian. Lihat Javadoc:sumber
Saya pikir JavaDoc telah menjelaskan perbedaan secara eksplisit. Kebanyakan orang tahu bahwa CountDownLatch tidak dapat diatur ulang, namun, CyclicBarrier bisa. Tapi ini bukan satu-satunya perbedaan, atau CyclicBarrier dapat diubah namanya menjadi ResetbleCountDownLatch. Kita harus memberi tahu perbedaan dari perspektif tujuan mereka, yang dijelaskan dalam JavaDoc
CountDownLatch: Alat bantu sinkronisasi yang memungkinkan satu atau lebih utas menunggu hingga serangkaian operasi dilakukan pada utas lainnya selesai.
CyclicBarrier: Alat bantu sinkronisasi yang memungkinkan satu set utas untuk semua menunggu satu sama lain untuk mencapai titik penghalang bersama.
Di countDownLatch, ada satu atau lebih utas, yang sedang menunggu satu set utas lainnya selesai. Dalam situasi ini, ada dua jenis utas, satu jenis menunggu, jenis lain sedang melakukan sesuatu, setelah menyelesaikan tugas mereka, mereka bisa menunggu atau diakhiri.
Di CyclicBarrier, hanya ada satu jenis utas, mereka saling menunggu, mereka sama.
sumber
Perbedaan utama didokumentasikan tepat di Javadocs untuk CountdownLatch. Yaitu:
sumber 1.6 Javadoc
sumber
CountDownLatch digunakan untuk sinkronisasi satu kali. Saat menggunakan CountDownLatch, utas apa pun diizinkan untuk memanggil countDown () sebanyak yang mereka suka. Utas yang disebut await () diblokir hingga hitungannya mencapai nol karena panggilan ke countDown () oleh utas lain yang tidak dicekal. The javadoc untuk status CountDownLatch :
Sebaliknya, penghalang siklik digunakan untuk beberapa titik sinkronisasi, misalnya jika serangkaian thread menjalankan perhitungan loop / bertahap dan perlu disinkronkan sebelum memulai iterasi / fase berikutnya. Sesuai javadoc untuk CyclicBarrier :
Berbeda dengan CountDownLatch, setiap panggilan untuk menunggu () milik beberapa fase dan dapat menyebabkan utas untuk memblokir sampai semua pihak yang termasuk dalam fase itu telah meminta menunggu (). Tidak ada operasi countDown () eksplisit yang didukung oleh CyclicBarrier.
sumber
Pertanyaan ini sudah cukup dijawab, tetapi saya rasa saya bisa memberi nilai tambah sedikit dengan memposting beberapa kode.
Untuk menggambarkan perilaku penghalang siklik, saya telah membuat beberapa kode sampel. Segera setelah penghalang berujung, ia secara otomatis diatur ulang sehingga dapat digunakan kembali (oleh karena itu disebut "siklik"). Saat Anda menjalankan program, amati bahwa cetakan "Ayo main" dipicu hanya setelah penghalang dimiringkan.
sumber
Ketika saya mempelajari tentang kait dan penghalang siklik, saya menemukan metafora ini. cyclicbarriers : Bayangkan sebuah perusahaan memiliki ruang pertemuan. Untuk memulai pertemuan, sejumlah peserta rapat harus datang ke pertemuan (untuk menjadikannya resmi). berikut ini adalah kode peserta rapat biasa (seorang karyawan)
karyawan bergabung dengan rapat, menunggu orang lain datang untuk memulai rapat. juga dia akan keluar jika pertemuan dibatalkan :) maka kita memiliki THE BOSS bagaimana dosis tidak suka menunggu orang lain muncul dan jika dia kehilangan pasiennya, dia membatalkan pertemuan.
Pada hari normal, karyawan datang ke rapat menunggu yang lain muncul dan jika beberapa peserta tidak datang, mereka harus menunggu tanpa batas waktu! dalam beberapa pertemuan khusus, bos datang dan dia tidak suka menunggu. (5 orang perlu memulai rapat tetapi hanya bos yang datang dan juga karyawan yang antusias) sehingga dia membatalkan rapat (dengan marah)
Keluaran:
Ada skenario lain di mana utas luar orang lain (gempa bumi) membatalkan pertemuan (metode reset panggilan). dalam hal ini semua utas menunggu dibangunkan oleh pengecualian.
menjalankan kode akan menghasilkan keluaran lucu:
Anda juga dapat menambahkan sekretaris ke ruang rapat, jika rapat diadakan, dia akan mendokumentasikan semuanya tetapi dia bukan bagian dari rapat:
Kait : jika bos yang marah ingin mengadakan pameran untuk pelanggan perusahaan, semua hal harus siap (sumber daya). kami memberikan daftar tugas yang harus dilakukan setiap pekerja (Utas) dosis pekerjaannya dan kami memeriksa daftar yang harus dilakukan (beberapa pekerja melukis, yang lain menyiapkan sistem suara ...). ketika semua item dalam daftar yang harus dilakukan sudah lengkap (sumber daya disediakan) kami dapat membuka pintu bagi pelanggan.
Dan para pekerja bagaimana mempersiapkan pameran:
sumber
Singkatnya , hanya untuk memahami perbedaan fungsional utama antara keduanya:
dan
kecuali, tentu saja, fitur-fitur seperti non-blocking, menunggu waktunya, diagnostik dan segala sesuatu yang telah secara rinci dijelaskan dalam jawaban di atas.
Kelas-kelas di atas, bagaimanapun, berfungsi penuh dan setara, dalam fungsionalitas yang disediakan, sesuai dengan nama koresponden mereka.
Pada catatan yang berbeda,
CountDownLatch
adalah kelas dalam subkelasAQS
, saatCyclicBarrier
menggunakanReentrantLock
(kecurigaan saya adalah bisa sebaliknya atau keduanya bisa menggunakan AQS atau keduanya menggunakan Kunci - tanpa kehilangan efisiensi kinerja)sumber
Satu perbedaan yang jelas adalah, hanya N thread yang dapat menunggu pada CyclicBarrier of N untuk dirilis dalam satu siklus. Tetapi jumlah utas yang tidak terbatas dapat menunggu pada CountDownLatch dari N. Penurunan jumlah mundur dapat dilakukan dengan satu utas N kali atau utas N satu kali masing-masing atau kombinasi.
sumber
Dalam kasus CyclicBarrier, segera setelah SEMUA utas anak mulai memanggil barrier.await (), Runnable dieksekusi di Barrier. Penghalang. Tunggu di setiap utas anak akan membutuhkan waktu yang berbeda untuk menyelesaikannya, dan semuanya selesai pada waktu yang sama.
sumber
Di CountDownLatch , utas utama menunggu utas lainnya untuk menyelesaikan eksekusi. Di CyclicBarrier , utas pekerja menunggu satu sama lain untuk menyelesaikan eksekusi mereka.
Anda tidak dapat menggunakan kembali contoh CountDownLatch yang sama setelah hitungan mencapai ke nol dan kait terbuka, di sisi lain CyclicBarrier dapat digunakan kembali dengan mengatur ulang Barrier, Setelah penghalang rusak.
sumber
CountDownLatch adalah hitungan mundur dari apa pun; CyclicBarrier adalah hitungan mundur untuk utas saja
anggap ada 5 utas pekerja dan satu utas pengirim, dan ketika pekerja menghasilkan 100 barang, pengirim akan mengirimkannya.
Untuk CountDownLatch, penghitung bisa berada di pekerja atau item
Untuk CyclicBarrier, penghitung hanya bisa pada pekerja
Jika seorang pekerja jatuh tertidur tanpa batas, dengan CountDownLatch pada item, Pengirim dapat mengirim; Namun, dengan CyclicBarrier, Pengirim tidak pernah bisa dipanggil
sumber
@Kevin Lee dan @Jon saya mencoba CyclicBarrier dengan Runnable Opsional. Sepertinya itu berjalan di awal dan setelah CyclicBarrier berujung. Ini kode dan keluarannya
penghalang CyclicBarrier statis;
Keluaran
sumber