Mekanisme interupsi utas menyediakan metode untuk membangunkan utas dari menunggu pemblokiran, mencoba mengganggu aliran pemrosesan utas target yang ada dan menanggapi perintah baru. Java meninggalkan kebebasan ini untuk pengembang, dan kita harus memanfaatkannya dengan baik.
Hari ini kita akan berbicara tentang mekanisme interupsi benang java.
Mekanisme interupsi utas menyediakan metode yang memiliki dua kegunaan umum:
Bangunkan utas dari memblokir menunggu dan buat pemrosesan "interupsi terkontrol" yang sesuai.
Cobalah untuk menginformasikan utas target: Harap selarut aliran pemrosesan yang ada dan tanggapi perintah baru.
Ambil tujuan pertama sebagai contoh, silakan lihat kode berikut:
disinkronkan (lock) {coba {while (! check ()) {lock.wait (1000); }} catch (InterruptedException e) {E.PrintStackTrace (); }}Kode ini menggunakan mekanisme tunggu/beri tahu yang disediakan oleh Java. Eksekusi utas lock.Wait () akan memblokir. Ada tiga situasi untuk mengembalikan utas yang akan dijalankan.
1. Timeout 1000ms berakhir, dan kode berikutnya dieksekusi secara normal.
2. Utas lain menjalankan kode berikut untuk bangun secara aktif
sinkronisasi (lock) {lock.notifyall (); // atau lock.notify ();}Ini juga akan menjalankan kode berikutnya secara normal.
3. Benang lain yang diperlukan untuk menunggu adalah "mengganggu"
// Dapatkan referensi ke utas waiting utas A; a.interrupt ();
Thread A yang "terputus" akan melempar pengecualian Exception interrupted di lock.Wait ().
Singkatnya, Anda dapat berpikir objek.Wait () melakukan hal -hal ini secara internal:
boolean checkTimeout = timeout> 0; thread current = thread.currentThread (); lock.addwaiter (saat ini); while (! current.isnotified ()) {if (current.isInterrupted ()) {current.clearinterrupted (); Lempar interupsi baru (); } if (checkTimeout) {if (timeout == 0) break; Timeout--; }}Ini tidak sepenuhnya akurat, karena tunggu tidak menggunakan metode "jajak pendapat sibuk" ini untuk memeriksa, tetapi logika menilai bit bendera sudah benar.
Mari kita mulai dengan operasi "masalah interuprika secara manual" yang disebutkan di atas
// sun.nio.ch.interruptiblePublic Intercible {void interrupt (thread var1);} // java.lang.threadprivate volatile blocker interruptible; private final objek blockerlock = new objek (); public void interrupt () {if (this! = thread.currentthread ()); void void () {if (this! = Thread.currentthread ()) chellowcs public () {if (this! = thread.currentthread ()) check -check -publ disinkronkan (blockerlock) {interruptible b = blocker; if (b! = null) {interrupt0 (); B. Interrupt (ini); kembali; }} interrupt0 ();} // Hanya untuk mengatur interrupt native void interrupt0 ();Dapat dilihat bahwa utas. Jika utas saat ini mengalami gangguan NIO, itu juga akan menelepon kembali.
Perhatikan bahwa interrupt0 () cukup mengatur bendera interupsi utas.
Apa yang terjadi ketika utas tidak menghalangi dan tidak ada di area yang tidak dikendalikan oleh logika program Java, seperti objek.Wait (), thread.join (), thread.sleep ()? Jawabannya adalah bahwa tidak ada yang akan terjadi, dan apakah utas itu terputus hanya dapat diketahui dengan secara aktif memeriksa bendera interupsi.
Bagaimana cara memeriksa? Thread memperlihatkan dua antarmuka, thread.interrupted () dan thread.isInterrupted ().
// java.lang.threadpublic static boolean interrupted () {return currentThread (). is Intercrupted (true);} public boolean is interuprupted () {return terputus (false);} private asli boolean terputus (boolean clearInterrupted);Dapat dilihat bahwa keduanya mengandalkan internal terputus (boolean), yang akan mengembalikan apakah utas terganggu dan membersihkan bendera interupsi sesuai kebutuhan.
Ketika sebuah fungsi panggilan blok, fungsi pustaka java menandai melempar interruptedException dalam tanda tangan sumber pemblokiran dan memerlukan tulis mencoba menangkap untuk menangani interupsi.
Ketika utas memblokir, seperti yang disebutkan di atas, Java memeriksa bendera interupsi, menghapusnya terlebih dahulu, dan kemudian melempar Exception interrupted.
// java.lang.objectpublic final void tunggu () melempar interruptedException {tunggu (0);} public final void void tunggu (jual lama) melempar interruptedException;Jika utas menerima ExterruptedException dan kemudian menjalankan kode yang akan melempar pemblokiran, itu akan terus memblokir seperti "tidak peduli". Karena Java membersihkan bendera interupsi secara internal!
Kami sering menulis tiga jenis kode berikut yang menangani ExterruptException:
Tangani Exception Interrupted ke lapisan atas untuk diproses.
public void foo () melempar InterruptedException {disinkronkan (lock) {lock.wait (); }}InterruptedException mengatur ulang bit bendera interupsi.
coba {disinkronkan (lock) {lock.wait (); }} catch (InterruptedException e) {thread.currentThread (). Interrupt (); //merusak; }Selesaikan pekerjaan Anda terlebih dahulu, dan kemudian lemparkan Exception interrupted.
public void bar () melempar InterruptedException {InterruptedException IE = null; boolean selesai = false; while (! Done) {disinkronkan (lock) {coba {lock.wait (); } catch (InterruptedException e) {ie = e; melanjutkan; }} Done = true; } if (yaitu! = null) {throw IE; }}Jika utas mengabaikan bendera interupsi dan interrupted exception, itu masih berjalan dengan baik. Tapi ini bertentangan dengan niat asli kami untuk merancang multithreading. Kami ingin utas untuk bekerja sama secara harmonis dan dengan cara yang tertib untuk mencapai fungsi tertentu, sehingga utas yang terkontrol harus merespons interupsi. Dan kita harus memanfaatkan kebebasan ini dengan baik yang ditinggalkan oleh Java kepada pengembang.
Di atas adalah semua pengetahuan yang relevan tentang mekanisme interupsi utas Java yang diperkenalkan kepada Anda saat ini. Jika Anda tidak mengerti apa -apa, Anda dapat mendiskusikannya di area pesan di bawah ini. Terima kasih atas dukungan Anda untuk wulin.com.