Pengelompokan thread adalah fitur menarik yang disediakan oleh Java concurrency API. Kita dapat memperlakukan sekelompok thread sebagai unit independen dan dapat memanipulasi objek thread dalam grup thread sesuka hati. Misalnya, Anda dapat mengontrol sekelompok thread untuk menjalankan tugas yang sama tanpa peduli berapa banyak thread yang masih berjalan, dan Anda juga dapat menggunakan panggilan interupsi untuk menghentikan eksekusi semua thread.
Java menyediakan kelas ThreadGroup untuk mengontrol grup thread. Grup thread dapat dibuat melalui objek thread, atau dapat dibuat oleh grup thread lain untuk menghasilkan struktur pohon dari thread.
Menurut "Java Efektif", penggunaan ThreadGroup tidak lagi disarankan. Disarankan untuk menggunakan Executor.
——D Guagot menjelaskan hal ini.
Di bagian ini, kami menggunakan ThreadGroup untuk mengembangkan contoh sederhana. Kami akan membuat sepuluh thread dengan waktu tidur yang berbeda-beda (seperti simulasi pencarian) dan ketika salah satunya selesai, hentikan sisanya.
mengetahuinya
Ikuti langkah-langkah yang ditunjukkan di bawah ini untuk menyelesaikan kode contoh.
1. Buat kelas bernama Result untuk menyimpan nama thread pertama yang menyelesaikan tugas. Deklarasikan variabel pribadi bertipe String, nama, dan hasilkan metode Setter/Getter. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
kelas publik Hasil {
nama String pribadi;
String publik getName() {
nama kembali;
}
public void setName(Nama string) {
ini.nama = nama;
}
}
2. Buat kelas bernama SearchTask dan implementasikan antarmuka Runnable. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
kelas publik SearchTask mengimplementasikan Runnable {
3. Deklarasikan variabel privat bertipe Result dan buat instance variabel tersebut melalui konstruktor. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
hasil hasil pribadi;
Tugas Pencarian publik(Hasil hasil) {
this.hasil = hasil;
}
4. Implementasikan metode run() dan panggil metode doTask() di dalamnya untuk menunggu penyelesaian atau gangguan. Metode ini juga mencetak informasi ke konsol untuk menunjukkan awal, akhir, atau gangguan thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
@Mengesampingkan
menjalankan kekosongan publik() {
Nama string = Thread.currentThread().getName();
System.out.printf("Utas %s: Mulai/n", nama);
mencoba {
melakukan Tugas();
hasil.setName(nama);
} tangkapan (InterruptedException e) {
System.out.printf("Thread %s: Terganggu/n", nama);
kembali;
}
System.out.printf("Utas %s: Akhir/n", nama);
}
5. Menerapkan metode doTask(), yang akan membuat objek Acak dan kemudian menggunakan objek tersebut untuk menghasilkan nomor acak guna menyesuaikan waktu tidur thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
// Simulasikan pencarian
private void doTask() melempar InterruptedException {
Acak acak = Acak baru(Tanggal baru().getTime());
int nilai = (int) (acak.nextDouble() * 100);
System.out.printf("Utas %s: %d/n",
Thread.currentThread().getName(), value);
TimeUnit.SECONDS.sleep(nilai);
}
6. Buat kelas utama dari program contoh, Main, dan implementasikan metode main(). Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
kelas publik Utama {
public static void main(String[] args) {
7. Buat objek ThreadGroup bernama Searcher. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
ThreadGroup threadGroup = new ThreadGroup("Pencari");
8. Kemudian, buat objek Result dan objek SearchTask. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Hasil hasil = Hasil baru();
SearchTask searchTask = SearchTask baru(hasil);
9. Gunakan objek SearchTask untuk membuat sepuluh objek Thread, dan saat membuat objek Thread, teruskan objek ThreadGroup sebagai parameter pertama ke konstruktor kelas Thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
untuk (int saya = 0; saya < 5; saya++) {
Thread thread = Thread baru (threadGroup, searchTask);
thread.mulai();
mencoba {
TimeUnit.SECONDS.sleep(1);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
}
10. Gunakan metode list() untuk mencetak informasi objek ThreadGroup. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
System.out.printf("Jumlah Thread: %d/n", threadGroup.activeCount());
System.out.println("Informasi tentang Grup Thread");
threadGroup.daftar();
11. Gunakan activeCount() dan enumerate() untuk mendapatkan jumlah thread aktif di objek ThreadGroup dan salin ke array thread. Gunakan metode get*() untuk mendapatkan nama dan status thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Utas[] utas = Utas baru[threadGroup.activeCount()];
threadGroup.enumerate(utas);
untuk (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Utas %s: %s/n", utas[i].getName(),
utas[i].getState());
}
12. Panggil metode waitFinish() dan tunggu hingga salah satu thread di objek ThreadGroup menyelesaikan tugasnya. Terapkan metode ini nanti. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
tungguSelesai(grup utas);
13. Gunakan metode interupsi() untuk menginterupsi thread lain dalam grup thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
threadGroup.interrupt();
14. Terapkan metode waitFinish() dan gunakan metode activeCount() untuk mengontrol hasil eksekusi thread. Kodenya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
// Tunggu hingga tugas selesai
private static void waitFinish(ThreadGroup threadGroup) {
sementara (threadGroup.activeCount() > 9) {
mencoba {
TimeUnit.SECONDS.sleep(1);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
}
}
15. Jalankan program dan periksa efek eksekusi.
tahu kenapa
Berikut adalah hasil eksekusi program. Anda akan melihat output dari metode list(), status setiap thread, dll.
Copy kode kodenya sebagai berikut:
Utas Utas-0: Mulai
Utas Utas-0: 52
Thread Thread-1: Mulai
Utas Utas-1 : 41
Thread Thread-2: Mulai
Utas Utas-2 : 69
Thread Thread-3: Mulai
Benang Benang-3 : 60
Thread Thread-4: Mulai
Benang Benang-4 : 88
Jumlah Thread: 5
Informasi tentang Grup Thread
java.lang.ThreadGroup[nama=Pencari,maxpri=10]
Thread[Thread-0,5,Pencari]
Thread[Thread-1,5,Pencari]
Thread[Thread-2,5,Pencari]
Thread[Thread-3,5,Pencari]
Thread[Thread-4,5,Pencari]
Utas Utas-0: TIMED_WAITING
Utas Utas-1: TIMED_WAITING
Utas Utas-2: TIMED_WAITING
Utas Utas-3: TIMED_WAITING
Utas Utas-4: TIMED_WAITING
Thread Thread-1: Terputus
Thread Thread-4 : Terputus
Thread Thread-2 : Terputus
Thread Thread-0: Terganggu
Thread Thread-3: Terganggu
Kelas ThreadGroup menyimpan banyak objek Thread dan objek ThreadGroup terkait. Anda dapat mengakses informasi thread dengan memanggil metode kelas ini, dan Anda juga dapat melakukan berbagai operasi padanya, seperti interupsi.
tidak pernah berakhir
Kelas ThreadGroup juga memiliki banyak metode. Silakan baca dokumentasi API untuk deskripsi metode lengkap.
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
Di bawah ini adalah versi lengkap kode yang digunakan dalam contoh di bagian ini.
Kode lengkap kelas Hasil:
Copy kode kodenya sebagai berikut:
paket com.diguage.books.concurrencycookbook.chapter1.recipe10;
/**
* Simpan hasil kueri
* Tanggal: 30-09-2013
* Waktu: 00:45
*/
kelas publik Hasil {
nama String pribadi;
String publik getName() {
nama kembali;
}
public void setName(Nama string) {
ini.nama = nama;
}
}
Kode lengkap kelas SearchTask adalah sebagai berikut:
paket com.diguage.books.concurrencycookbook.chapter1.recipe10;
import java.util.Date;
import java.util.Acak;
import java.util.bersamaan.TimeUnit;
/**
* Kelas pencarian simulasi
* Tanggal: 02-10-2013
* Waktu: 22:38
*/
kelas publik SearchTask mengimplementasikan Runnable {
hasil hasil pribadi;
Tugas Pencarian publik(Hasil hasil) {
this.hasil = hasil;
}
@Mengesampingkan
menjalankan kekosongan publik() {
Nama string = Thread.currentThread().getName();
System.out.printf("Utas %s: Mulai/n", nama);
mencoba {
melakukan Tugas();
hasil.setName(nama);
} tangkapan (InterruptedException e) {
System.out.printf("Thread %s: Terganggu/n", nama);
kembali;
}
System.out.printf("Utas %s: Akhir/n", nama);
}
// Simulasikan pencarian
private void doTask() melempar InterruptedException {
Acak acak = Acak baru(Tanggal baru().getTime());
int nilai = (int) (acak.nextDouble() * 100);
System.out.printf("Utas %s: %d/n",
Thread.currentThread().getName(), value);
TimeUnit.SECONDS.sleep(nilai);
}
}
Kode lengkap kelas Utama:
Copy kode kodenya sebagai berikut:
paket com.diguage.books.concurrencycookbook.chapter1.recipe10;
import java.util.bersamaan.TimeUnit;
/**
* Contoh grup thread kelas utama
* Tanggal: 02-10-2013
* Waktu: 22:45
*/
kelas publik Utama {
public static void main(String[] args) {
ThreadGroup threadGroup = new ThreadGroup("Pencari");
Hasil hasil = Hasil baru();
SearchTask searchTask = SearchTask baru(hasil);
untuk (int saya = 0; saya < 5; saya++) {
Thread thread = Thread baru (threadGroup, searchTask);
thread.mulai();
mencoba {
TimeUnit.SECONDS.sleep(1);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
}
System.out.printf("Jumlah Thread: %d/n", threadGroup.activeCount());
System.out.println("Informasi tentang Grup Thread");
threadGroup.daftar();
Utas[] utas = Utas baru[threadGroup.activeCount()];
threadGroup.enumerate(utas);
untuk (int i = 0; i < threadGroup.activeCount(); i++) {
System.out.printf("Utas %s: %s/n", utas[i].getName(),
utas[i].getState());
}
tungguSelesai(grup utas);
threadGroup.interrupt();
}
// Tunggu hingga tugas selesai
private static void waitFinish(ThreadGroup threadGroup) {
sementara (threadGroup.activeCount() > 9) {
mencoba {
TimeUnit.SECONDS.sleep(1);
} tangkapan (InterruptedException e) {
e.printStackTrace();
}
}
}
}