1. Pengenalan
Dalam artikel ringkas ini, kita akan membahas menghentikan Thread di Java - yang tidak semudah itu kerana kaedah Thread.stop () sudah tidak digunakan lagi.
Seperti yang dijelaskan dalam kemas kini ini dari Oracle, stop () dapat menyebabkan objek yang dipantau rusak.
2. Menggunakan Bendera
Mari mulakan dengan kelas yang membuat dan memulakan utas. Tugas ini tidak akan berakhir dengan sendirinya, jadi kami memerlukan beberapa cara untuk menghentikan utas itu.
Kami akan menggunakan bendera atom untuk itu:
public class ControlSubThread implements Runnable { private Thread worker; private final AtomicBoolean running = new AtomicBoolean(false); private int interval; public ControlSubThread(int sleepInterval) { interval = sleepInterval; } public void start() { worker = new Thread(this); worker.start(); } public void stop() { running.set(false); } public void run() { running.set(true); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something here } } }
Daripada mempunyai gelung sementara menilai kebenaran tetap , kita menggunakan AtomicBoolean dan sekarang kita dapat memulakan / menghentikan pelaksanaan dengan menetapkannya menjadi benar / salah.
Seperti yang dijelaskan dalam pengenalan kami kepada Atomic Variables, menggunakan AtomicBoolean mencegah konflik dalam menetapkan dan memeriksa pemboleh ubah dari rangkaian yang berbeza.
3. Mengganggu Benang
Apa yang berlaku ketika tidur () diatur ke selang waktu yang lama, atau jika kita sedang menunggu kunci yang mungkin tidak pernah dilepaskan?
Kami menghadapi risiko menyekat untuk jangka masa yang panjang atau tidak akan berhenti dengan bersih.
Kita boleh membuat gangguan () untuk situasi ini, mari kita tambahkan beberapa kaedah dan bendera baru ke kelas:
public class ControlSubThread implements Runnable { private Thread worker; private AtomicBoolean running = new AtomicBoolean(false); private int interval; // ... public void interrupt() { running.set(false); worker.interrupt(); } boolean isRunning() { return running.get(); } boolean isStopped() { return stopped.get(); } public void run() { running.set(true); stopped.set(false); while (running.get()) { try { Thread.sleep(interval); } catch (InterruptedException e){ Thread.currentThread().interrupt(); System.out.println( "Thread was interrupted, Failed to complete operation"); } // do something } stopped.set(true); } }
Kami telah menambahkan kaedah interrupt () yang menetapkan bendera berjalan kami ke false dan memanggil kaedah interrupt () thread pekerja .
Sekiranya utas sedang tidur ketika ini dipanggil, tidur () akan keluar dengan InterruptException, seperti juga panggilan penyekat lain.
Ini mengembalikan utas ke gelung, dan ia akan keluar kerana menjalankan adalah salah.
4. Kesimpulan
Dalam tutorial ringkas ini, kami melihat bagaimana menggunakan pemboleh ubah atom, yang digabungkan dengan panggilan untuk mengganggu (), untuk menutup benang dengan bersih. Ini semestinya lebih baik daripada memanggil kaedah berhenti () yang tidak digunakan lagi dan berisiko mengunci selamanya dan kerosakan memori.
Seperti biasa, kod sumber penuh tersedia di GitHub.