Apakah ada keuntungan menggunakan
java.util.concurrent.CountdownLatch
dari pada
java.util.concurrent.Semaphore ?
Sejauh yang saya tahu, fragmen berikut hampir setara:
1. Semaphore
final Semaphore sem = new Semaphore(0);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
sem.release();
}
}
};
t.start();
}
sem.acquire(num_threads);
2: CountDownLatch
final CountDownLatch latch = new CountDownLatch(num_threads);
for (int i = 0; i < num_threads; ++ i)
{
Thread t = new Thread() {
public void run()
{
try
{
doStuff();
}
finally
{
latch.countDown();
}
}
};
t.start();
}
latch.await();
Kecuali jika dalam kasus # 2 kait tidak dapat digunakan kembali dan yang lebih penting Anda perlu mengetahui sebelumnya berapa banyak utas yang akan dibuat (atau tunggu sampai semuanya dimulai sebelum membuat kait.)
Jadi, dalam situasi apa gerendel lebih disukai?
CountDownLatch digunakan untuk memulai serangkaian utas dan kemudian menunggu sampai semuanya selesai (atau sampai mereka memanggil
countDown()
beberapa kali.Semaphore digunakan untuk mengontrol jumlah thread bersamaan yang menggunakan sumber daya. Sumber daya itu bisa berupa file, atau bisa jadi cpu dengan membatasi jumlah utas yang dieksekusi. Hitungan Semaphore bisa naik dan turun sebagai thread yang berbeda memanggil
acquire()
danrelease()
.Dalam contoh Anda, Anda pada dasarnya menggunakan Semaphore sebagai semacam Count UP Latch. Mengingat bahwa niat Anda adalah menunggu semua utas selesai, menggunakan
CountdownLatch
membuat niat Anda lebih jelas.sumber
Ringkasan singkat:
Semaphore
danCountDownLatch
melayani tujuan yang berbeda.Gunakan
Semaphore
untuk mengontrol akses utas ke sumber daya.Gunakan
CountDownLatch
untuk menunggu penyelesaian semua utasSemaphore
definisi dari Javadocs:Namun, sebenarnya tidak ada objek izin yang digunakan; yang
Semaphore
hanya menyimpan hitungan jumlah yang tersedia dan bertindak sesuai.Bagaimana cara kerjanya?
Semaphore digunakan untuk mengontrol jumlah thread bersamaan yang menggunakan resource. Resource tersebut dapat berupa data bersama, atau blok kode ( bagian kritis ) atau file apa pun.
Hitungan
Semaphore
dapat naik dan turun sebagai utas yang berbeda memanggilacquire()
danrelease()
. Tetapi pada titik waktu mana pun, Anda tidak dapat memiliki lebih banyak jumlah utas lebih dari jumlah Semaphore.Semaphore
Kasus penggunaan:Lihat artikel ini untuk penggunaan semafor.
CountDownLatch
definisi dari Javadocs:Bagaimana cara kerjanya?
CountDownLatch
bekerja dengan memiliki penghitung yang diinisialisasi dengan jumlah utas, yang berkurang setiap kali utas menyelesaikan eksekusinya. Saat hitungan mencapai nol, itu berarti semua utas telah menyelesaikan eksekusinya, dan utas yang menunggu di kait melanjutkan eksekusi.CountDownLatch
Kasus penggunaan:Lihat artikel ini untuk memahami
CountDownLatch
konsep dengan jelas.Lihat juga Fork Join Pool di artikel ini . Ini memiliki beberapa kesamaan dengan
CountDownLatch
.sumber
Katakanlah Anda masuk ke toko profesional golf, berharap menemukan berempat,
Ketika Anda mengantre untuk mendapatkan waktu tee dari salah satu petugas toko profesional, pada dasarnya Anda menelepon
proshopVendorSemaphore.acquire()
, begitu Anda mendapatkan waktu tee, Anda menelepon.proshopVendorSemaphore.release()
Catatan: salah satu petugas gratis dapat melayani Anda, yaitu sumber daya bersama.Sekarang Anda berjalan ke starter, dia memulai
CountDownLatch(4)
dan memanggilawait()
untuk menunggu orang lain, untuk bagian Anda, Anda menelepon check-in yaituCountDownLatch
.countDown()
dan begitu pula yang berempat. Ketika semua tiba, starter memberi pergi (await()
panggilan kembali)Sekarang, setelah sembilan hole ketika Anda masing-masing mengambil break, secara hipotetis melibatkan starter lagi, dia menggunakan 'baru'
CountDownLatch(4)
untuk tee off Hole 10, wait / sync yang sama seperti Hole 1.Namun, jika starter menggunakan a
CyclicBarrier
untuk memulai, dia dapat mengatur ulang instance yang sama di Lubang 10 alih-alih kait kedua, yang menggunakan & melempar.sumber
Melihat sumber yang tersedia secara gratis, tidak ada keajaiban dalam implementasi kedua kelas tersebut, jadi kinerjanya harus hampir sama. Pilih salah satu yang membuat niat Anda lebih jelas.
sumber
CountdownLatch
membuat utas menunggu padaawait()
metode, sampai saat hitungan telah mencapai nol. Jadi mungkin Anda ingin semua utas menunggu hingga 3 pemanggilan sesuatu, lalu semua utas bisa masuk. ALatch
umumnya tidak dapat diatur ulang.A
Semaphore
mengizinkan utas untuk mengambil izin, yang mencegah terlalu banyak utas dijalankan sekaligus, memblokir jika tidak bisa mendapatkan izin yang diperlukan untuk melanjutkan. Izin dapat dikembalikan keSemaphore
memungkinkan utas menunggu lainnya untuk melanjutkan.sumber