Pada bagian sebelumnya "Interupsi Thread", kami menjelaskan cara menginterupsi thread yang sedang berjalan dan apa yang harus kita lakukan pada Thread agar dapat menginterupsi thread. Secara umum, kita dapat menggunakan mekanisme interupsi yang diperkenalkan pada bagian sebelumnya. Namun, jika thread mengimplementasikan algoritma kompleks yang didistribusikan ke beberapa metode, atau jika ada panggilan rekursif dalam pemanggilan metode, kita harus menggunakan cara yang lebih baik untuk mengontrol interupsi thread. Untuk tujuan ini, Java menyediakan InterruptedException. Pengecualian ini dapat terjadi ketika permintaan interupsi terdeteksi dan ditangkap dalam metode run().
Di bagian ini, kita akan menggunakan thread untuk mencari file di direktori tertentu dan subdirektorinya untuk mendemonstrasikan pengendalian interupsi thread dengan menggunakan InterruptedException.
mengetahuinya
Ikuti langkah-langkah yang ditunjukkan di bawah ini untuk mengimplementasikan program contoh.
1. Buat kelas bernama FileSearch dan implementasikan antarmuka Runnable. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
FileSearch kelas publik mengimplementasikan Runnable {
2. Deklarasikan dua variabel, satu untuk nama file yang akan dicari, dan satu lagi untuk menginisialisasi direktori yang akan dicari; mengimplementasikan konstruktor kelas, dan menginisialisasi kedua variabel yang baru saja dideklarasikan dengan parameter konstruktor. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
String initPath pribadi;
Nama file String pribadi;
Pencarian Berkas publik(String initPath, String Namafile) {
ini.initPath = initPath;
this.namafile = namafile;
}
3. Terapkan metode run(), yang memeriksa apakah nama file adalah nama jalur. Jika ya, panggil metode DirectoryProcess() untuk memprosesnya. Metode direktoriProcess() memunculkan InterruptedException, jadi kita perlu menangkap pengecualiannya. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
@Mengesampingkan
menjalankan kekosongan publik() {
File file = File baru(initPath);
if (file.isDirectory()) {
mencoba {
direktoriProses(file);
} tangkapan (InterruptedException e) {
System.out.printf("%s: Pencarian terhenti",
Thread.currentThread().getName());
}
}
}
Dalam artikel asli, nama metode yang disebutkan adalah processDirectory(). Namun, menurut prosedur di bawah ini, ini merupakan kesalahan administrasi. Jadi perbaikilah.
4. Implementasikan metode DirectoryProcess(). Metode ini membaca semua file dan subdirektori di direktori yang ditentukan dan kemudian memprosesnya. Untuk setiap direktori, metode ini melakukan panggilan rekursif untuk memproses direktori yang ditentukan oleh parameter. Untuk setiap file, metode ini memanggil metode fileProcess(). Setelah memproses semua direktori dan file, metode ini akan memeriksa apakah thread terputus, yaitu memunculkan pengecualian InterruptedException. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
/**
* Proses direktori
*
* Direktori file @param yang akan diproses
* @melempar InterruptedException
*/
direktori void pribadiProses(File file) melempar InterruptedException {
File[] daftar = file.listFiles();
jika (batal != daftar) {
for (int i = 0; i < daftar.panjang; i++) {
jika (daftar[i].isDirectory()) {
direktoriProses(daftar[i]);
} kalau tidak {
fileProses(daftar[i]);
}
}
}
if (Utas.interrupted()) {
melempar InterruptedException();
}
}
5. Menerapkan metode fileProcess() yang membandingkan file yang sedang diproses dengan nama file yang akan ditemukan. Jika nama file sama, sebuah pesan dicetak ke konsol. Thread kemudian memeriksa untuk melihat apakah itu terputus, dan jika demikian, melemparkan InterruptedException. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
/**
* File yang diproses
*
* @param file file yang akan diproses
* @melempar InterruptedException
*/
private void fileProcess(File file) melempar InterruptedException {
if (file.getName().equals(fileName)) {
Sistem.keluar.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Utas.interrupted()) {
melempar InterruptedException();
}
}
6. Sekarang, implementasikan kelas utama dari contoh dan implementasikan metode main(). Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
kelas publik Utama {
public static void main(String[] args) {
7. Buat dan inisialisasi objek FileSearch, lalu buat objek Thread untuk melakukan tugas tersebut. Kemudian, mulai threadnya. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Pencarian File pencarian file = Pencarian File baru("C://", "autoexec.bat");
Utas utas = Utas baru (pencarian file);
thread.mulai();
8. Tunggu sepuluh detik lalu putuskan threadnya. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
mencoba {
TimeUnit.SECONDS.sleep(10);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
9. Jalankan contoh dan lihat hasilnya.
tahu kenapa
Berikut hasil eksekusi thread. Dapat dilihat dari output bagaimana eksekusi thread dihentikan ketika FileSearch mendeteksi adanya gangguan.
Copy kode kodenya sebagai berikut:
Utas-0: C:/autoexec.bat
Thread-0: Pencarian terhenti
Dalam contoh ini, kami menggunakan pengecualian Java untuk mengontrol interupsi thread. Saat Anda menjalankan contoh, program memeriksa apakah direktori tertentu dan subdirektorinya berisi file target. Misalnya, jika Anda memasukkan /b/c/d, program akan memanggil metode direktoriProcess() secara rekursif sebanyak tiga kali. Ketika thread mendeteksi bahwa thread tersebut telah terputus, InterruptedException akan dilemparkan tidak peduli berapa banyak panggilan rekursif yang dilakukan, program akan mulai mengeksekusi metode run().
tidak pernah berakhir
Pengecualian InterruptedException umumnya diberikan oleh API konkurensi Java, seperti metode sleep().
Gunakan doktrin
Artikel ini diterjemahkan dari "Buku Masak Konkurensi Java 7" (D Gua Ge mencurinya sebagai "Koleksi Contoh Konkurensi Java7") dan hanya digunakan sebagai bahan pembelajaran. Ini tidak boleh digunakan untuk tujuan komersial apa pun tanpa izin.
Keberhasilan kecil
Kode lengkap kelas FileSearch adalah sebagai berikut:
paket com.diguage.books.concurrencycookbook.chapter1.recipe4;
impor java.io.File;
/**
* Tanggal: 18-09-2013
* Waktu: 18:21
*/
FileSearch kelas publik mengimplementasikan Runnable {
String initPath pribadi;
Nama file String pribadi;
/**
* Konstruktor inisialisasi
*
* @param initPath Direktori yang akan dicari
* @param fileName Nama file yang akan ditemukan
*/
Pencarian Berkas publik(String initPath, String Namafile) {
ini.initPath = initPath;
this.namafile = namafile;
}
@Mengesampingkan
menjalankan kekosongan publik() {
File file = File baru(initPath);
if (file.isDirectory()) {
mencoba {
direktoriProses(file);
} tangkapan (InterruptedException e) {
System.out.printf("%s: Pencarian terhenti",
Thread.currentThread().getName());
}
}
}
/**
* Proses direktori
*
* Direktori file @param yang akan diproses
* @melempar InterruptedException
*/
direktori void pribadiProses(File file) melempar InterruptedException {
File[] daftar = file.listFiles();
jika (batal != daftar) {
for (int i = 0; i < daftar.panjang; i++) {
jika (daftar[i].isDirectory()) {
direktoriProses(daftar[i]);
} kalau tidak {
fileProses(daftar[i]);
}
}
}
if (Utas.interrupted()) {
melempar InterruptedException();
}
}
/**
* File yang diproses
*
* @param file file yang akan diproses
* @melempar InterruptedException
*/
private void fileProcess(File file) melempar InterruptedException {
if (file.getName().equals(fileName)) {
Sistem.keluar.printf("%s : %s/n",
Thread.currentThread().getName(),
file.getAbsolutePath());
}
if (Utas.interrupted()) {
melempar InterruptedException();
}
}
}
Kode lengkap kelas Utama
Copy kode kodenya sebagai berikut:
paket com.diguage.books.concurrencycookbook.chapter1.recipe4;
import java.util.bersamaan.TimeUnit;
/**
* Tanggal: 18-09-2013
* Waktu: 19:28
*/
kelas publik Utama {
public static void main(String[] args) {
Pencarian File pencarian file = Pencarian File baru("C://", "autoexec.bat");
Utas utas = Utas baru (pencarian file);
thread.mulai();
mencoba {
TimeUnit.SECONDS.sleep(10);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
thread.interrupt();
}
}