Bagaimana anda membunuh jawa.lang.Thread
di Jawa?
Melihat ini thread oleh Matahari pada mengapa mereka ditinggalkan Benang.stop()
. Ia pergi ke detail tentang mengapa ini adalah metode yang buruk dan apa yang harus dilakukan untuk berhenti dengan aman benang pada umumnya.
Cara yang mereka sarankan adalah dengan menggunakan shared variabel sebagai bendera yang meminta latar belakang benang untuk berhenti. Variabel ini kemudian dapat ditetapkan oleh objek yang berbeda meminta benang mengakhiri.
Umumnya anda don't..
Anda meminta untuk mengganggu apapun itu lakukan dengan menggunakan Thread.interrupt() (javadoc link)
Penjelasan yang baik mengapa di awal di sini (jawa technote link)
Di Jawa benang yang tidak dibunuh, tetapi berhenti dari thread ini dilakukan di a cara kooperatif. Thread diminta untuk menghentikan dan benang kemudian dapat shutdown dengan anggun.
Sering volatile boolean
field ini digunakan benang yang secara berkala memeriksa dan berakhir ketika diatur ke nilai yang sesuai.
I tidak akan gunakan boolean
untuk memeriksa apakah thread yang harus pergi. Jika anda menggunakan volatile
sebagai bidang pengubah, ini akan bekerja handal, tapi jika kode anda menjadi lebih kompleks, karena bukan menggunakan metode pemblokiran lainnya dalam sementara
loop, hal ini mungkin terjadi, bahwa kode anda akan tidak menghentikan pada semua atau setidaknya membutuhkan waktu yang lebih lama seperti yang anda mungkin ingin.
Tertentu yang menghalangi metode perpustakaan dukungan gangguan.
Setiap thread sudah boolean flag terganggu status dan anda harus memanfaatkannya. Hal ini dapat dilaksanakan seperti ini:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Kode sumber diadaptasi dari Jawa Concurrency dalam Praktek. Sejak batal()
metode umum anda dapat membiarkan thread lain memanggil metode ini seperti yang anda inginkan.
Salah satu cara adalah dengan menetapkan kelas variabel dan menggunakannya sebagai sentinel.
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
Set eksternal variabel kelas, yaitu bendera = true pada contoh di atas. Set ke false untuk 'membunuh' benang.
Ada cara bagaimana anda bisa melakukan itu. Tetapi jika anda harus menggunakannya, baik anda adalah buruk programmer atau anda menggunakan kode yang ditulis oleh programmer. Jadi, anda harus berpikir tentang berhenti menjadi buruk programmer atau berhenti menggunakan kode yang buruk. Solusi ini hanya untuk situasi ketika TIDAK ADA CARA LAIN.
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
Saya ingin menambahkan beberapa observasi, berdasarkan komentar-komentar yang telah terakumulasi.
I'd vote untuk Benang.stop()
.
Seperti misalnya anda memiliki tahan lama operasi (seperti permintaan jaringan). Seharusnya kau menunggu respon, tapi itu bisa memakan waktu dan pengguna berlayar ke UI lainnya. Ini menunggu thread sekarang) yang tidak berguna b) potensi masalah karena ketika dia akan mendapatkan hasil, it's benar-benar tidak berguna dan ia akan memicu callback yang dapat menyebabkan jumlah kesalahan.
Semua itu dan dia dapat melakukan respon pengolahan yang bisa CPU intens. Dan anda, sebagai pengembang, bahkan tidak bisa menghentikannya, karena anda dapat't membuang if (Thread.currentThread().isInterrupted())
garis di semua kode.
Jadi ketidakmampuan untuk paksa stop thread ini aneh.
Pertanyaan ini agak samar-samar. Jika anda berarti "bagaimana cara menulis sebuah program sehingga benang berhenti berjalan ketika aku ingin", maka berbagai tanggapan lain harus membantu. Tapi jika yang anda maksudkan "saya memiliki darurat dengan server saya tidak bisa me-restart sekarang dan aku hanya membutuhkan benang khusus untuk mati, datang apa yang mungkin", maka anda memerlukan sebuah alat intervensi untuk mencocokkan alat pemantauan seperti jstack
.
Untuk tujuan ini saya buat jkillthread. Lihat petunjuk untuk penggunaan.
Tentu saja ada kasus di mana anda menjalankan beberapa jenis tidak-benar-benar-kode dipercaya. (Saya pribadi ini dengan memungkinkan upload script untuk mengeksekusi dalam lingkungan Jawa. Ya, ada security alarm bell berdering di mana-mana, tapi itu's bagian dari aplikasi.) Di malang misalnya, anda pertama-tama adalah hanya sedang berharap dengan meminta penulis naskah untuk menghormati beberapa jenis boolean run/don't-run sinyal. Anda hanya layak aman gagal untuk memanggil metode berhenti di thread jika, katakanlah, ini berjalan lebih lama dari beberapa timeout.
Tapi, ini hanya "layak", dan tidak mutlak, karena kode bisa menangkap ThreadDeath kesalahan (atau apa pun kecuali anda secara eksplisit melempar), dan tidak rethrow itu seperti sopan benang yang seharusnya dilakukan. Jadi, intinya adalah AFAIA tidak ada yang mutlak gagal aman.
Tidak ada cara untuk anggun membunuh benang.
Anda dapat mencoba untuk mengganggu benang, satu commons strategi adalah dengan menggunakan pil racun untuk pesan benang untuk berhenti sendiri
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
@Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
Umumnya anda don't membunuh, berhenti, atau mengganggu thread (atau memeriksa mau terganggu()), tetapi membiarkan hal itu menghentikan secara alami.
Ini adalah sederhana. Anda dapat menggunakan loop bersama-sama dengan (mudah menguap) variabel boolean dalam run() metode untuk mengontrol thread's kegiatan. Anda juga dapat kembali aktif dari thread ke thread utama untuk menghentikannya.
Dengan cara ini anda anggun membunuh thread :) .
Upaya tiba-tiba benang penghentian terkenal buruk pemrograman praktek dan bukti miskin aplikasi desain. Semua thread dalam aplikasi multi-threaded secara eksplisit dan implisit berbagi proses yang sama negara dan dipaksa untuk bekerja sama dengan satu sama lain untuk tetap konsisten, jika tidak, aplikasi anda akan rentan terhadap bug yang akan benar-benar sulit untuk mendiagnosa. Jadi, ini adalah tanggung jawab dari pengembang untuk memberikan jaminan konsistensi seperti melalui hati-hati dan jelas desain aplikasi.
Ada dua utama solusi tepat untuk dikendalikan benang terminasi:
Baik dan penjelasan rinci tentang masalah-masalah yang berkaitan dengan mendadak benang penghentian serta contoh-contoh yang salah dan solusi tepat untuk dikendalikan benang penghentian dapat ditemukan di sini:
Berikut ini adalah beberapa baik membaca pada subjek:
Aku't mendapatkan interupsi untuk bekerja di Android, jadi saya menggunakan metode ini, bekerja dengan sempurna:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
'Membunuh benang' bukan kalimat yang tepat untuk digunakan. Berikut adalah salah satu cara kita dapat menerapkan anggun selesai/keluar dari benang pada akan:
Runnable yang saya digunakan:
`` kelas TaskThread mengimplementasikan Runnable {
boolean shouldStop;
publik TaskThread(boolean shouldStop) { ini.shouldStop = shouldStop; }
@Override public void run() {
Sistem.keluar.println("Benang telah mulai");
sementara (!shouldStop) { // melakukan sesuatu }
Sistem.keluar.println("Benang telah berakhir");
}
public void stop() { shouldStop = true; }
} ``
Memicu kelas:
`` public class ThreadStop {
public static void main(String[] args) {
Sistem.keluar.println("Mulai");
// Memulai thread TaskThread tugas = new TaskThread(false); Thread t = new Thread(tugas); t.start();
// Menghentikan thread tugas.stop();
Sistem.keluar.println("Akhir");
}
} ``