Motivasi
- Sejak Java 5, platform ini telah menawarkan utiliti konkurensi peringkat tinggi dalam pakej java.util.concurrent.
- Mereka menggantikan penggunaan manual dan kompleks untuk menunggu dan memberitahu.
- Ia lebih selamat dan lebih mudah digunakan, mengurangkan kemungkinan ralat dalam kod serentak.
Utiliti Concurrency dalam java.util.concurrent
Kategori utiliti:
- Rangka Kerja Pelaksana: Pengurusan benang diliputi dalam Item 80.
- Koleksi serentak: Pelaksanaan koleksi standard yang selamat untuk benang seperti Senarai, Baris Gilir dan Peta.
- Penyegerak: Penyelarasan antara utas, termasuk CountDownLatch, Semaphore, CyclicBarrier, Exchanger dan Phaser.
Koleksi Bersaing
Ciri:
- Disegerakkan secara dalaman untuk prestasi tinggi.
- Mereka tidak membenarkan pengecualian aktiviti bersaing.
- Operasi atom seperti putIfAbsent meningkatkan keselamatan dan kebolehgunaan.
Contoh: Pelaksanaan Peta selamat benang:
Map<String, String> map = new ConcurrentHashMap<>();
String result = map.putIfAbsent("key", "value");
if (result == null) {
System.out.println("Valor inserido.");
} else {
System.out.println("Chave já existente com valor: " + result);
}
Kebaikan:
- Ganti koleksi disegerakkan (Collections.synchronizedMap).
- Peningkatan ketara dalam prestasi aplikasi bersaing.
Penyegerak
Tujuan: Penyelarasan antara urutan.
Contoh penyegerak biasa:
- CountDownLatch: Penghalang sekali guna untuk penyelarasan benang.
- Semaphore: Kawal akses kepada sumber yang dikongsi.
- CyclicBarrier: Penyegerakan pada titik penghalang boleh guna semula.
- Fasa: Penyegerakan benang lanjutan dan dinamik.
Contoh Praktikal: Masa Serentak dengan CountDownLatch
Objektif: Mengukur masa pelaksanaan beberapa utas secara serentak.
Pelaksanaan:
public static long time(Executor executor, int concurrency, Runnable action) throws InterruptedException {
CountDownLatch ready = new CountDownLatch(concurrency);
CountDownLatch start = new CountDownLatch(1);
CountDownLatch done = new CountDownLatch(concurrency);
for (int i = 0; i < concurrency; i++) {
executor.execute(() -> {
try {
ready.countDown(); // Indica que está pronto
start.await(); // Aguarda o sinal de início
action.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
done.countDown(); // Indica que terminou
}
});
}
ready.await(); // Aguarda todas as threads ficarem prontas
long startTime = System.nanoTime();
start.countDown(); // Dispara o sinal de início
done.await(); // Aguarda todas as threads finalizarem
return System.nanoTime() - startTime;
}
Nota:
- Menggunakan tiga selak: sedia (menunjukkan kesediaan), mula (pencetus awal) dan selesai (pemuktamad).
- Menggunakan System.nanoTime untuk mengukur selang masa dengan tepat.
Amalan semasa dengan tunggu dan maklumkan
Hanya diperlukan untuk penyelenggaraan kod warisan.
Peraturan utama:
- Sentiasa gunakan gelung apabila memanggil tunggu:
synchronized (lock) {
while (!condition) {
lock.wait();
}
}
- Uji keadaan sebelum dan selepas menunggu.
- Elakkan pergantungan pada notify, pilih notifyAll.
Kesimpulan
- Gunakan utiliti kompetitif apabila boleh.
- Mereka menjadikan kod lebih mudah dibaca, selamat dan cekap.
- Alternatif moden (seperti CyclicBarrier atau Phaser) boleh menggantikan corak berasaskan menunggu dan pemberitahuan
Contoh daripada buku




Atas ialah kandungan terperinci Item Lebih suka utiliti concurrency untuk menunggu dan memberitahu. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!
Kenyataan:Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn