1. Pendahuluan
Artikel ini mencatat beberapa poin pengetahuan tentang mekanisme interupsi dalam java multithreading. Ini terutama terdiri dari perbedaan antara metode stop, interrupted () dan is interrupted (), dan melakukan analisis sederhana dari implementasi kode sumber.
Ada 3 cara untuk mengakhiri utas berjalan di java
① Benang keluar secara normal, yaitu, metode run () telah dieksekusi
② Gunakan metode stop () di kelas utas untuk secara paksa menghentikan utas. Namun, metode stop () telah kedaluwarsa dan tidak disarankan untuk menggunakannya
③Gunakan mekanisme interupsi
Tidak ada yang bisa dilakukan saat utas keluar secara normal. Mekanisme interupsi diperkenalkan secara rinci di bawah ini. Mari pertama -tama lihat kode sumber metode stop (). Kuncinya adalah komentar pada kode sumber. Ini menjelaskan mengapa stop () tidak aman, utas mana yang dihentikan dengan metode stop ()?
/*** Memaksa utas untuk berhenti mengeksekusi.* <p>* Jika ada manajer keamanan yang diinstal, metode <code> checkAccess </code>* dipanggil dengan <code> ini </code>* sebagai argumennya. Ini dapat mengakibatkan* <code> SecurityException </code> dinaikkan (di utas saat ini).* <p>* Jika utas ini berbeda dari utas saat ini (yaitu, utas saat ini sedang mencoba menghentikan utas selain dari dirinya sendiri), penambahan* Code Manager "di dalam" CODEAD "ADICUDE (dengan kode" CODEAD ") </CODED ADICUDE (dengan CODEAD (CODERED (CODEAD" ADICUDE (dengan CODEAD (CODERED (CODEAD (CODERE (CODERE (CODERE (CODERE (CODERE (CODERE (CODERE (CODERE (CODED (CODED (CODE (CODE (CODE (CODE (CODE (CODE (CODE (CODE) Melempar* <code> SecurityException </code> (di utas saat ini).* <p>* utas yang diwakili oleh utas ini dipaksa untuk menghentikan apa pun* itu melakukan hal yang tidak normal dan untuk segera terjadi. Catch* <code> ThreadDeath </code> Kecuali jika itu harus melakukan beberapa operasi pembersihan* yang luar biasa (perhatikan bahwa lemparan* <code> threaddeath </code> menyebabkan <code> akhirnya </code> klausa* <code> Coba </code> Pernyataan yang akan dieksekusi sebelum utas* secara resmi mati). Jika A <code> Catch </code> Klausul menangkap objek* <code> ThreadDeath </code>, penting untuk memperbaiki objek* sehingga utas tersebut benar-benar mati.* <p>* Pengawasan kesalahan tingkat atas yang bereaksi terhadap pengecualian yang tidak dikerjakan. tidak dapat* memodifikasi utas ini.* @see #interrupt ()* @see #CheckAccess ()* @see #run ()* @see #Start ()* @Leaddeath* @see ThreadGroup #UncaughtException (Thread, Threadable)* @See SecurityManager #checkAccess (Thread)* @see SecuritySe #checkkmeer. Menghentikan utas dengan* thread. Stop menyebabkannya membuka kunci semua monitor yang* telah dikunci (sebagai konsekuensi alami dari pengecualian* <code> threaddeath </code> yang tidak dicentang menyebarkan tumpukan). Jika* salah satu objek yang sebelumnya dilindungi oleh monitor ini berada dalam* keadaan yang tidak konsisten, benda -benda yang rusak menjadi terlihat oleh* utas lain, yang berpotensi menghasilkan perilaku sewenang -wenang. Banyak* penggunaan <code> berhenti </code> harus diganti dengan kode yang cukup* memodifikasi beberapa variabel untuk menunjukkan bahwa utas target harus* berhenti berjalan. Utas target harus memeriksa variabel ini* secara teratur, dan kembali dari metode yang dijalankan secara tertib* jika variabel menunjukkan bahwa ia harus berhenti berjalan. Jika* Thread target menunggu untuk waktu yang lama (pada variabel kondisi,* misalnya), metode <code> interupsi </code> harus digunakan untuk* mengganggu tunggu.* Untuk informasi lebih lanjut, lihat* <a href = "{@docroot} /../ technotes/guides/concurrency/concurrency/threadprimitiedeprication Tercerahkan? </a>.*/@DeprecatedPublic final void stop () {stop (new threadDeath ());}Seperti yang dikomentari di atas, baris 9 hingga 16 menunjukkan bahwa metode stop () dapat menghentikan "utas lain". Utas yang mengeksekusi metode thread.stop () disebut utas saat ini, sedangkan "utas lain" adalah utas yang diwakili oleh utas objek yang memanggil metode thread.stop ().
menyukai:
public static void main (string [] args) {mythread thread = mythread baru ... // .... thread.stop (); // ..}Dalam metode utama, utas saat ini adalah utas utama. Ini dieksekusi ke baris 4 dan ingin menghentikan utas "utas lain". Utas lainnya adalah utas yang diwakili oleh objek utas dari kelas MyThread baru.
Baris 21 hingga 23 menunjukkan bahwa utas yang belum dimulai dapat dihentikan. Efeknya adalah: Ketika utas dimulai, segera berakhir.
Komentar setelah baris 48 menunjukkan mengapa metode stop () sudah usang! Mengapa itu tidak aman.
Misalnya, Threada Thread memiliki monitor yang bertanggung jawab untuk melindungi sumber daya kritis tertentu, seperti jumlah transfer bank. Ketika proses transfer sedang berlangsung, utas utama memanggil metode threada.stop (). Akibatnya, monitor dilepaskan, dan sumber daya yang dilindungi (jumlah transfer) cenderung tidak konsisten. Misalnya, akun A telah menurun 100, sedangkan akun B belum meningkat 100.
Kedua, mekanisme interupsi
Ada terlalu banyak detail tentang cara menggunakan mekanisme interupsi dengan benar di Java. Metode interrupted () dan iSintrupted () mencerminkan apakah utas saat ini dalam keadaan terganggu.
① terputus ()
/*** menguji apakah utas saat ini telah terganggu. Status* <i> yang terputus </i> dari utas dibersihkan dengan metode ini. Dengan kata lain, jika metode ini dipanggil dua kali berturut -turut, panggilan kedua akan mengembalikan false (kecuali utas saat ini* terputus lagi, setelah panggilan pertama telah menyelesaikan status* yang terganggu dan sebelum panggilan kedua telah memeriksanya). ** <p> Urutan yang diabaikan oleh Metode ini. terputus;* <code> false </code> sebaliknya.* @see #isInterrupted ()* @Revised.*/public static boolean interrupted () {return currentThread (). is Intercrupted (true);}Dari komentar dalam kode sumber, ia menguji keadaan interupsi utas saat ini, dan metode ini akan menghapus status interupsi.
②IsInterrupted ()
/*** menguji apakah utas ini telah terganggu. Status <i> interrupted* </i> dari utas tidak terpengaruh oleh metode ini. ** <p> Gangguan utas diabaikan karena utas tidak hidup* pada saat interupsi akan tercermin dengan metode ini* mengembalikan false. ** @Return <code> true </code> jika utas ini telah terganggu;* <kode>* code </code. isInterrupted () {return isintrupted (false);}Seperti yang dapat dilihat dari komentar kode sumber, metode isInterrupted () tidak akan menghapus status interupsi.
③Difference antara metode interrupted () dan iSintrupted () Metode
Seperti yang dapat dilihat dari kode sumber, kedua metode disebut terputus (boolean clearinterrupted), kecuali bahwa satu dengan parameter itu benar dan yang lainnya dengan parameternya salah.
/*** Tes Jika beberapa utas telah terganggu. Keadaan terputus* diatur ulang atau tidak berdasarkan nilai clearinterrupted yang* lulus.*/Boolean asli pribadi terputus (boolean clearinterrupted);
Oleh karena itu, perbedaan pertama adalah bahwa yang satu membersihkan bit bendera interupsi dan yang lainnya tidak menghapus bit bendera interupsi.
Setelah menganalisis kode sumber, Anda dapat melihat perbedaan kedua dalam pernyataan pengembalian:
public static boolean interrupted () {return currentThread (). is Intercrupted (true);}/********************/public boolean terputus () {return terputus (false);}interrupted () menguji keadaan terputus dari utas saat ini. ISinterrupted () menguji utas yang diwakili oleh objek yang memanggil metode tersebut. Salah satunya adalah metode statis (ini menguji keadaan interupsi utas saat ini), dan yang lainnya adalah metode instan (ia menguji keadaan interupsi utas yang diwakili oleh objek instan).
Berikut ini adalah contoh spesifik untuk lebih memperjelas perbedaan ini.
Ada kelas utas khusus sebagai berikut:
kelas publik mythread memperluas utas {@Overridepublic void run () {super.run (); untuk (int i =; i <; i ++) {System.out.println ("i =" + (i +));}}}Pertama -tama mari kita lihat contoh metode interrupted ():
kelas publik run {public static void main (string [] args) {try {mythread thread = new MyThread (); thread.start (); thread.sleep (); thread.interrupt (); // thread.currentThread (). Interrupt (); System.out.println ("stop? ="+Thread.interrupted ()); // falsesystem.out.println ("stop? ="); // ...Baris 5 memulai utas utas, dan baris 6 membuat utas utama tidur selama 1 detik, sehingga utas utas memiliki kesempatan untuk mendapatkan eksekusi CPU.
Setelah utas utama tidur untuk 1s, ia melanjutkan eksekusi ke baris 7 dan permintaan untuk mengganggu utas utas.
Baris 9 menguji apakah utas dalam keadaan terputus. Utas mana yang sedang diuji di sini? ? ? Jawabannya adalah utas utama. Karena:
(1) interrupted () menguji status interupsi utas saat ini
(2) Utas utama menjalankan pernyataan baris ke -9, jadi utas utama adalah utas saat ini
Mari kita lihat contoh metode isInterrupted ():
kelas publik run {public static void main (string [] args) {try {mythread thread = new mythread (); thread.start (); thread.sleep (); thread.interrupt (); System.out.println ("apakah itu stop? ="+thread.isInterrupted ()); // true ("apakah itu berhenti? ="+thread.isInterrupted ());On Line 8, Metode ISInterrupted () dipanggil oleh objek utas. Oleh karena itu, keadaan interupsi utas yang diwakili oleh objek utas diuji. Karena pada baris 7, utas utama meminta untuk mengganggu utas utas, hasilnya pada baris 8 adalah: true