Bisakah Anda menjelaskan apa yang java.lang.Thread.interrupt()
dilakukan ketika dipanggil?
Bisakah Anda menjelaskan apa yang java.lang.Thread.interrupt()
dilakukan ketika dipanggil?
Jawaban:
Thread.interrupt()
mengatur status / bendera terputus dari utas target. Kemudian kode yang berjalan di utas target itu MUNGKIN mengumpulkan status terputus dan menanganinya dengan tepat. Beberapa metode yang memblokir seperti Object.wait()
dapat langsung mengkonsumsi status terputus dan melemparkan pengecualian yang sesuai (biasanya InterruptedException
)
Gangguan di Jawa tidak bersifat pre-emptive. Dengan kata lain kedua utas harus bekerja sama untuk memproses interupsi dengan benar. Jika utas target tidak menyurvei status terputus, interupsi secara efektif diabaikan.
Polling terjadi melalui Thread.interrupted()
metode yang mengembalikan status terputus utas saat ini DAN menghapus tanda tersebut. Biasanya utas kemudian dapat melakukan sesuatu seperti melempar InterruptedException.
EDIT (dari komentar Thilo): Beberapa metode API telah dibangun dalam penanganan interupsi. Dari atas kepala saya ini termasuk.
Object.wait()
,, Thread.sleep()
danThread.join()
java.util.concurrent
strukturInterruptedException
, alih-alih menggunakan ClosedByInterruptException
.EDIT (dari jawaban @ thomas-pornin untuk pertanyaan yang sama persis untuk kelengkapan)
Interupsi utas adalah cara yang lembut untuk mendorong utas. Ini digunakan untuk memberi kesempatan pada thread untuk keluar dengan bersih , sebagai lawan dari Thread.stop()
itu lebih seperti menembak utas dengan senapan serbu.
Apa itu interupsi?
Interupsi adalah indikasi untuk utas bahwa ia harus menghentikan apa yang dilakukannya dan melakukan sesuatu yang lain. Terserah programmer untuk memutuskan dengan tepat bagaimana sebuah thread merespon interupsi, tetapi sangat umum bagi thread untuk mengakhiri.
Bagaimana penerapannya?
Mekanisme interupsi diimplementasikan menggunakan bendera internal yang dikenal sebagai status interupsi. Invoking Thread.interrupt mengatur flag ini. Ketika utas memeriksa interupsi dengan menjalankan metode statis Thread.interrupted, status interupsi dihapus. Thread.isInterrupted non-statis, yang digunakan oleh satu utas untuk menanyakan status interupsi yang lain, tidak mengubah bendera status interupsi.
Kutipan dari Thread.interrupt()
API :
Mengganggu utas ini. Pertama metode checkAccess dari utas ini dipanggil, yang dapat menyebabkan SecurityException dilempar.
Jika utas ini diblokir dalam permohonan metode wait (), wait (long), atau wait (long, int) dari kelas Object, atau dari join (), join (long), join (long, int) , sleep (long), atau sleep (long, int), metode kelas ini, maka status interruptnya akan dihapus dan ia akan menerima InterruptedException.
Jika utas ini diblokir dalam operasi I / O pada saluran interruptible maka saluran akan ditutup, status interupsi utas akan ditetapkan, dan utas akan menerima ClosedByInterruptException.
Jika utas ini diblokir dalam Pemilih maka status interupsi utas akan ditetapkan dan akan segera kembali dari operasi pemilihan, mungkin dengan nilai bukan nol, sama seperti jika metode bangun pemilih dipanggil.
Jika tidak ada kondisi sebelumnya yang bertahan maka status interupsi utas ini akan ditetapkan.
Lihat ini untuk pemahaman lengkap tentang hal yang sama:
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Jika utas yang ditargetkan telah menunggu (dengan menelepon wait()
, atau beberapa metode terkait lainnya yang pada dasarnya melakukan hal yang sama, seperti sleep()
), itu akan terputus, artinya berhenti menunggu apa yang ditunggu dan menerima InterruptedException sebagai gantinya.
Ini sepenuhnya tergantung pada utas itu sendiri (kode yang memanggil wait()
) untuk memutuskan apa yang harus dilakukan dalam situasi ini. Itu tidak secara otomatis menghentikan utas.
Kadang-kadang digunakan dalam kombinasi dengan bendera penghentian. Ketika terputus, utas dapat memeriksa bendera ini, lalu menutupnya sendiri. Tetapi sekali lagi, ini hanya sebuah konvensi.
Untuk kelengkapan, di samping jawaban lain, jika utas terputus sebelum ia memblokir Object.wait(..)
atau Thread.sleep(..)
lain - lain, ini setara dengan itu terputus segera setelah memblokir pada metode itu , seperti yang ditunjukkan contoh berikut.
public class InterruptTest {
public static void main(String[] args) {
Thread.currentThread().interrupt();
printInterrupted(1);
Object o = new Object();
try {
synchronized (o) {
printInterrupted(2);
System.out.printf("A Time %d\n", System.currentTimeMillis());
o.wait(100);
System.out.printf("B Time %d\n", System.currentTimeMillis());
}
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("C Time %d\n", System.currentTimeMillis());
printInterrupted(3);
Thread.currentThread().interrupt();
printInterrupted(4);
try {
System.out.printf("D Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("E Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("F Time %d\n", System.currentTimeMillis());
printInterrupted(5);
try {
System.out.printf("G Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("H Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("I Time %d\n", System.currentTimeMillis());
}
static void printInterrupted(int n) {
System.out.printf("(%d) Am I interrupted? %s\n", n,
Thread.currentThread().isInterrupted() ? "Yes" : "No");
}
}
Keluaran:
$ javac InterruptTest.java
$ java -classpath "." InterruptTest
(1) Am I interrupted? Yes
(2) Am I interrupted? Yes
A Time 1399207408543
WAS interrupted
C Time 1399207408543
(3) Am I interrupted? No
(4) Am I interrupted? Yes
D Time 1399207408544
WAS interrupted
F Time 1399207408544
(5) Am I interrupted? No
G Time 1399207408545
H Time 1399207408668
I Time 1399207408669
Implikasi: jika Anda mengulangi seperti berikut, dan interupsi terjadi pada saat yang tepat ketika kontrol telah pergi Thread.sleep(..)
dan berkeliling loop, pengecualian masih akan terjadi. Jadi, sangat aman untuk mengandalkan InterruptedException yang andal dilemparkan setelah utas terputus :
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread.interrupt()
mengatur status / bendera terputus dari utas target menjadi true yang bila diperiksa menggunakan Thread.interrupted()
dapat membantu menghentikan utas tak berujung. Rujuk http://www.yegor256.com/2015/10/10/interrupted-exception.html
Interupsi utas didasarkan pada status interupsi bendera . Untuk setiap utas nilai default dari status interupsi disetel ke false . Kapanpun metode interupsi () dipanggil pada utas, status interupsi disetel ke true .
public void interrupt ()
Mengganggu utas ini.
Kecuali jika utas saat ini mengganggu dirinya sendiri, yang selalu diizinkan, metode checkAccess dari utas ini dipanggil, yang dapat menyebabkan SecurityException dilempar.
Jika utas ini diblokir dalam permohonan metode wait (), wait (long), atau wait (long, int) dari kelas Object, atau dari join (), join (long), join (long, int) , sleep (long), atau sleep (long, int), metode kelas ini, maka status interruptnya akan dihapus dan ia akan menerima InterruptedException.
Jika utas ini diblokir dalam operasi I / O pada saluran interruptible maka saluran akan ditutup, status interupsi utas akan ditetapkan, dan utas akan menerima ClosedByInterruptException.
Jika utas ini diblokir dalam Pemilih maka status interupsi utas akan ditetapkan dan akan segera kembali dari operasi pemilihan, mungkin dengan nilai bukan nol, sama seperti jika metode bangun pemilih dipanggil.
Jika tidak ada kondisi sebelumnya yang bertahan maka status interupsi utas ini akan ditetapkan.
Mengganggu utas yang tidak hidup tidak perlu memiliki efek apa pun.
Melempar: SecurityException - jika utas saat ini tidak dapat mengubah utas ini
Interupsi adalah indikasi untuk utas bahwa ia harus menghentikan apa yang dilakukannya dan melakukan sesuatu yang lain. Terserah programmer untuk memutuskan dengan tepat bagaimana sebuah thread merespon interupsi, tetapi sangat umum bagi thread untuk mengakhiri. Referensi yang sangat bagus: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Metode Thread.interrupt () menetapkan flag 'interrupt status' internal. Biasanya flag itu dicentang dengan metode Thread.interrupted ().
Dengan konvensi, metode apa pun yang ada melalui InterruptedException harus menghapus tanda status interupsi.