Apa itu kumpulan benang
Kumpulan utas adalah kumpulan utas yang [Eksekusi Loop] Beberapa logika aplikasi di satu atau lebih utas.
Secara umum, kumpulan benang memiliki bagian -bagian berikut:
Satu atau lebih utas yang menyelesaikan tugas utama.
Utas manajemen yang digunakan untuk manajemen penjadwalan.
Antrian tugas yang diperlukan untuk dieksekusi.
Fungsi kumpulan utas:
Fungsi kumpulan utas adalah membatasi jumlah utas yang dieksekusi dalam sistem.
Bergantung pada lingkungan sistem, jumlah utas dapat diatur secara otomatis atau manual untuk mencapai efek operasi terbaik; Lebih sedikit sumber daya sistem yang terbuang, dan lebih banyak kemacetan sistem tidak tinggi. Gunakan kumpulan utas untuk mengontrol jumlah utas, dan utas lainnya sedang mengantri. Setelah tugas dieksekusi, tugas pertama diambil dari antrian untuk memulai eksekusi. Jika tidak ada proses menunggu dalam antrian, sumber daya kumpulan utas ini sedang menunggu. Ketika tugas baru perlu dijalankan, jika ada utas pekerja yang menunggu di kumpulan utas, ia dapat mulai berjalan; Kalau tidak, itu akan memasuki antrian menunggu.
Terapkan kumpulan utas sendiri
Berdasarkan pemahaman di atas kumpulan utas, kami menulis kumpulan utas sederhana kami sendiri:
Antarmuka kumpulan utas sederhana:
Public Interface ThreadPool <Job Extends Runnable> {// Jalankan tugas (pekerjaan), pekerjaan ini harus menerapkan Runnable Void Execute (pekerjaan pekerjaan); // tutup shutdown batal pool utas (); // Tingkatkan utas pekerja, yaitu utas yang digunakan untuk menjalankan tugas addworker tugas (int num); // Kurangi utas pekerja membatalkan RemestWorker (int num); // Dapatkan jumlah tugas yang menunggu untuk dieksekusi batal getjobsize ();}Klien dapat mengirimkan pekerjaan ke kumpulan utas melalui metode eksekusi (pekerjaan) untuk dieksekusi, dan klien tidak harus menunggu pekerjaan dieksekusi sama sekali. Selain metode Execute (JOB), antarmuka kumpulan utas menyediakan metode untuk meningkatkan/mengurangi utas pekerja dan tutup kumpulan benang. Setiap klien mengirimkan pekerjaan yang akan memasuki antrian kerja dan menunggu utas pekerja untuk diproses.
Implementasi default antarmuka kumpulan utas
Public Class DefaultThreadPool <Job Extends Runnable> mengimplementasikan threadpool <cubp> {// Jumlah maksimum utas untuk utas pemeliharaan kumpulan utas utas private static static int int max_worker_numbers = 10; // Nilai default dari utas pemeliharaan kumpulan utas private static final int default_worker_numbers = 5; // Jumlah minimum utas pemeliharaan kumpulan utas thread private static final int min_worker_numbers = 1; // Pertahankan daftar kerja, yang menambahkan daftar final privat yang diprakarsai klien <job> Jobs = new LinkedList <Ecpling> (); // DAFTAR PEKERJA PEKERJAAN PRIBADI DAFTAR FINAL PRIBADI <WORKER> PERBAIKAN = collections.synchronizedList (ArrayList baru <Worker> ()); // jumlah utas pekerja int private int workernum; // menghasilkan threadnum atomiclong pribadi = atomiclong baru (); // Hasilkan Thread Pool publik DefaultThreadPool () {this.workernum = default_worker_numbers; Peworker (this.workernum); } public DefaultThreadPool (int num) {if (num> max_worker_numbers) {this.workernum = default_worker_numbers; } else {this.workernum = num; } inisialisasi pekerja (this.workernum); } // inisialisasi setiap utas pekerja private void initializeworkers (int num) {for (int i = 0; i <num; i ++) {pekerja pekerja = pekerja baru (); // Tambahkan ke daftar pekerja utas pekerja.add (pekerja); // mulai utas utas pekerja utas = utas baru (pekerja); thread.start (); }} public void mengeksekusi (pekerjaan pekerjaan) {if (job! = null) {// Menurut utas "tunggu/beri tahu mekanisme", kita harus mengunci pekerjaan yang disinkronkan (pekerjaan) {jobs.addlast (pekerjaan); jobs.notify (); }}} // Tutup kumpulan utas yang akan menutup setiap utas pekerja public void shutdown () {for (pekerja w: pekerja) {w.shutdown (); }}} // Tambahkan utas pekerja public void addWorkers (int num) {// Tambahkan kunci untuk mencegah utas meningkat atau menyelesaikan sementara utas berikutnya terus meningkat, menyebabkan utas pekerja melebihi nilai maksimum yang disinkronkan (Jobs) {if (num + this.workernum> max_worker_number) {num = max = num + this.workernum> max_worker_number) {num = max = num + this.workernum> max_worker_number) {num = max = num } initializeworkers (num); this.workernum += num; }} // Kurangi utas pekerja public void removeWorker (int num) {disinkronkan (jobs) {if (num> = this.workernum) {lempar baru ilegalargumentException ("melebihi jumlah utas yang ada"); } untuk (int i = 0; i <num; i ++) {pekerja pekerja = pekerja.get (i); if (pekerja! = null) {// tutup utas dan hapus worker.shutdown (); pekerja. }} this.workernum -= num; }} public int getJobsize () {// TODO Metode yang dihasilkan otomatis Stub return workers.size (); } // Tentukan kelas pekerja class worker mengimplementasikan runnable {// menunjukkan apakah pekerja volatile private volatile running = true; public void run () {while (running) {job job = null; // Thread tunggu/mekanisme pemberitahuan disinkronkan (Jobs) {if (jobs.isempty ()) {coba {jobs.wait (); // Thread tunggu untuk bangun} catch (interruptedException e) {// merasakan operasi interupsi eksternal pada utas, dan mengembalikan thread.currentThread (). kembali; }} // ambil pekerjaan pekerjaan = jobs.removefirst (); } // jalankan pekerjaan jika (job! = Null) {job.run (); }}} // Akhiri utas public void shutdown () {running = false; }}}
Dari implementasi kumpulan utas, dapat dilihat bahwa ketika klien memanggil metode eksekusi (pekerjaan), itu akan terus menambah pekerjaan ke pekerjaan daftar tugas, dan setiap utas pekerja tidak akan membaca pekerjaan dari pekerjaan untuk dieksekusi. Ketika pekerjaan kosong, utas pekerja memasuki keadaan menunggu.
Setelah menambahkan pekerjaan, metode notify () dipanggil pada pekerjaan antrian kerja untuk membangunkan utas pekerja. Di sini kami tidak menyebut notifyall () untuk menghindari pemborosan sumber daya dengan memindahkan semua utas dalam antrian menunggu untuk antrian pemblokiran.
Inti dari kumpulan utas adalah menggunakan antrian kerja yang aman untuk menghubungkan utas pekerja dan utas klien. Utas klien kembali setelah memasukkan tugas ke dalam antrian kerja, sementara utas pekerja salah arah mengambil pekerjaan dari antrian kerja dan menjalankannya. Ketika antrian kerja kosong, utas pekerja memasuki keadaan menunggu. Ketika klien mengirimkan tugas, itu akan melewati utas pekerja mana pun. Dengan pengajuan sejumlah besar tugas, lebih banyak utas pekerja dibangunkan.
Referensi: "Seni Pemrograman Bersamaan di Java" Fang Tengfei