Fungsi kondisi adalah untuk memberikan kontrol kunci yang lebih tepat. Metode menunggu () dalam kondisi setara dengan metode tunggu () objek, metode sinyal () dalam kondisi setara dengan metode pemberitahuan () objek, dan sinyalAll () dalam kondisi setara dengan metode pemberitahuan Objek (). Perbedaannya adalah bahwa metode tunggu (), notify (), dan notifyAll () dalam objek dibundel dengan "kunci yang disinkronkan" (kata kunci yang disinkronkan); dan kondisi perlu dibundel dengan "mutex"/"share lock".
Daftar Fungsi Kondisi
// menyebabkan utas saat ini menunggu sampai menerima sinyal atau terganggu. void menunggu () // menyebabkan utas saat ini tetap dalam keadaan tunggu sebelum menerima sinyal, terganggu, atau mencapai waktu tunggu yang ditentukan. Boolean menunggu (lama, unit timeunit) // menyebabkan utas saat ini berada dalam keadaan tunggu sampai menerima sinyal, terganggu, atau mencapai waktu tunggu yang ditentukan. Long Awaitnanos (Long Nanostimeout) // menyebabkan utas saat ini berada dalam keadaan menunggu sebelum menerima sinyal. void AwaitUninterruptible () // menyebabkan utas saat ini tetap dalam keadaan menunggu sampai menerima sinyal, terganggu, atau mencapai tenggat waktu yang ditentukan. Boolean Awaituntil (Batas Waktu Tanggal) // Bangunkan utas menunggu. void sinyal () // bangun semua utas menunggu. void SignalAll ()
Contoh Penggunaan Kelas Kondisi
Kondisi memecah metode monitor objek (tunggu, beri tahu, dan beri tahu semua) menjadi objek yang sama sekali berbeda sehingga dengan menggabungkan objek-objek ini dengan implementasi kunci apa pun, setiap objek menyediakan beberapa set menunggu (tunggu-set). Di antara mereka, kunci menggantikan penggunaan metode dan pernyataan yang disinkronkan, dan kondisi menggantikan penggunaan metode monitor objek. Berikut ini adalah contoh komunikasi utas yang ditulis sebelumnya dengan implementasi dengan kondisi, kode ini adalah sebagai berikut:
Public Class ThreadTest2 {public static void main (String [] args) {final Business Business = new Business (); utas baru (runnable baru () {@Override public void run () {threadExecute (bisnis, "sub");}}). start (); ThreadExecute (bisnis, "utama"); } public static void threadExecute (bisnis bisnis, string threadType) {for (int i = 0; i <100; i ++) {coba {if ("main" .equals (threadType)) {Business.main (i); } else {Business.sub (i); }} catch (InterruptedException e) {E.PrintStackTrace (); }}}} kelas bisnis {private boolean bool = true; kunci kunci pribadi = reentrantlock baru (); kondisi kondisi pribadi = lock.newcondition (); publik /*disinkronkan* / void main (int loop) melempar interruptedException {lock.lock (); coba {while (bool) {condition.aWait (); // this.wait (); } untuk (int i = 0; i <100; i ++) {System.out.println ("Utas utama seq dari" + i + ", loop" + loop); } bool = true; condition.signal (); // this.notify (); } akhirnya {lock.unlock (); }} public /*disinkronkan* / void sub (int loop) melempar interruptedException {lock.lock (); coba {while (! bool) {condition.await (); // this.wait (); } untuk (int i = 0; i <10; i ++) {System.out.println ("Sub thread seq dari" + i + ", loop" + loop); } bool = false; condition.signal (); // this.notify (); } akhirnya {lock.unlock (); }}} Dalam kondisi, ganti tunggu () dengan menunggu (), ganti notify () dengan sinyal (), dan ganti notifyall () dengan sinyalAll (). Metode komunikasi tradisional utas dapat diimplementasikan. Catatan di sini kondisi itu terikat pada kunci. Untuk membuat kunci, Anda harus menggunakan metode newCondition ().
Dengan cara ini, kondisi tidak berbeda dengan komunikasi utas tradisional. Kekuatan kondisi adalah bahwa ia dapat menetapkan kondisi yang berbeda antara beberapa utas. Berikut ini adalah sepotong kode dari API untuk diilustrasikan.
Class BoundedBuffer {final lock lock = baru reentrantlock (); // lock objek kondisi final notfull = lock.newcondition (); // tulis kondisi utas kondisi akhir notempty = lock.newcondition (); // Baca Kondisi Thread Object [] items = Objek baru [100]; // Cached Queue Int Putptr/Intptr/Intpr*Incupes*in indeks*, 100]; antrian*/; public void put (objek X) melempar InterruptedException {lock.lock (); Coba {while (count == items.length) // Jika antriannya penuh dengan khayalan. thread} akhirnya {lock.unlock (); }} objek publik Take () melempar InterruptedException {lock.lock (); coba {while (count == 0) // Jika antriannya kosong notempty.aWait (); // blokir objek utas baca x = item [takePtr]; // Pilih nilainya jika (++ takePtr == items.length) TakePtr = 0; // Jika indeks yang dibaca membaca posisi terakhir dari antrian, mengaturnya ke 0 - -count; } akhirnya {lock.unlock (); }}} Ini adalah area cache di lingkungan kerja multi-threaded. Area cache menyediakan dua metode: put dan ambil. Put adalah menyimpan data, mengambil adalah untuk mengambil data, dan ada antrian cache di dalamnya. Lihat kode untuk variabel dan deskripsi metode tertentu. Fungsi yang diimplementasikan oleh kelas area cache ini: beberapa utas menyimpan data dan mengambil data darinya. Nilai cache maksimum yang dapat dikenakan antrian cache (pertama, pertama, kemudian masuk, dan kemudian keluar) dapat cache adalah 100. Beberapa utas saling eksklusif. Ketika nilai yang disimpan dalam antrian cache mencapai 100, utas tulis akan diblokir dan utas baca akan dibangunkan. Ketika nilai yang disimpan dalam antrian cache adalah 0, utas baca akan diblokir dan utas tulis akan dibangunkan. Analisis berikut dari proses eksekusi kode:
1. Utas Tulis mengeksekusi dan memanggil metode put;
2. Untuk menentukan apakah jumlahnya 100, jelas tidak ada 100;
3. Lanjutkan untuk mengeksekusi dan menyetor nilainya;
4. Setelah menentukan posisi indeks yang saat ini ditulis ++, apakah sama dengan 100. menyamakan nilai indeks tulis dengan 0 dan hitung+1;
5. Bangun hanya satu dari antrian pemblokiran utas baca;
6. Jalankan utas baca dan hubungi metode Take;
7.…
8. Bangun hanya satu dari utas menulis antrian yang menghalangi.
Ini adalah kekuatan dari berbagai kondisi. Dengan asumsi bahwa antrian cache penuh, maka pemblokirannya jelas merupakan utas tulis, dan bangunnya pasti utas baca. Sebaliknya, pemblokirannya jelas merupakan utas baca, dan bangunnya pasti utas tulis. Jadi apa yang akan terjadi jika hanya ada satu kondisi? Antrian cache penuh, kunci ini tidak tahu apakah itu utas baca atau utas tulis. Jika bangun adalah utas baca, semua orang senang. Jika bangun adalah utas tulis, maka utasnya baru saja dibangunkan dan diblokir lagi, dan kemudian bangun lagi, yang membuang banyak waktu.