Artikel ini menganalisis empat penggunaan kumpulan utas Java untuk referensi Anda. Konten spesifiknya adalah sebagai berikut
1. Kerugian utas baru
Apakah Anda masih melakukan utas baru sebagai berikut saat menjalankan tugas yang tidak sinkron?
utas baru (runnable baru () {@Override public void run () {// TODO Metode yang dihasilkan otomatis Stub}}). start ();Maka Anda akan memiliki terlalu banyak out, kerugian utas baru adalah sebagai berikut:
A. Kinerja utas baru buruk setiap saat.
B. Utas tidak memiliki manajemen terpadu, yang dapat membuat utas baru tanpa batasan, bersaing satu sama lain, dan dapat menempati terlalu banyak sumber daya sistem untuk menyebabkan kerusakan atau OOM.
C. Kurangnya lebih banyak fungsi, seperti eksekusi waktu, eksekusi berkala, gangguan utas.
Dibandingkan dengan utas baru, keunggulan dari empat kumpulan utas yang disediakan oleh Java adalah:
A. Gunakan kembali utas yang ada untuk mengurangi overhead pembuatan dan kepunahan objek, dan berkinerja baik.
B. Ini dapat secara efektif mengontrol jumlah maksimum utas bersamaan, meningkatkan tingkat pemanfaatan sumber daya sistem, dan menghindari persaingan sumber daya yang berlebihan dan menghindari penyumbatan.
C. Menyediakan fungsi seperti eksekusi waktunya, eksekusi reguler, threading tunggal, kontrol angka bersamaan, dll.
2. Java Thread Pool
Java menyediakan empat jenis kumpulan benang melalui pelaksana, yaitu:
NewcachedThreadpool membuat kolam benang yang bisa di -cache. Jika panjang kumpulan utas melebihi kebutuhan pemrosesan, ia dapat mendaur ulang benang idle secara fleksibel. Jika tidak ada daur ulang, buat utas baru.
NewFixEdThreadPool membuat kumpulan benang panjang tetap yang dapat mengontrol jumlah maksimum concurrency utas, dan kelebihan utas akan menunggu dalam antrian.
NewsCheduledThreadPool membuat kumpulan benang panjang tetap yang mendukung eksekusi tugas yang tepat waktu dan berkala.
NewsingLetHreadExecutor membuat kumpulan utas berhadapan tunggal, yang hanya akan menggunakan utas pekerja yang unik untuk menjalankan tugas, memastikan bahwa semua tugas dieksekusi dalam urutan yang ditentukan (FIFO, LIFO, Prioritas).
(1) newcachedthreadpool:
Buat kumpulan utas yang dapat di -cache. Jika panjang pool utas melebihi kebutuhan pemrosesan, Anda dapat mendaur ulang benang idle secara fleksibel. Jika tidak ada daur ulang, buat utas baru. Kode sampel adalah sebagai berikut:
ExecutorService CachedThreadPool = Executors.NewCachedThreadPool (); untuk (int i = 0; i <10; i ++) {indeks int akhir = i; coba {thread.sleep (indeks * 1000); } catch (InterruptedException e) {E.PrintStackTrace (); } CachedThreadPool.Execute (runnable baru () {@Overridepublic void run () {System.out.println (index);}});}Kolam benang tidak terbatas. Ketika tugas kedua dieksekusi, tugas pertama telah selesai, dan utas yang mengeksekusi tugas pertama akan digunakan kembali tanpa membuat utas baru setiap saat.
(2) newfixedthreadpool:
Buat kumpulan benang panjang tetap yang dapat mengontrol jumlah maksimum concurrency utas, dan kelebihan utas akan menunggu dalam antrian. Kode sampel adalah sebagai berikut:
ExecutorService FixedThreadPool = Executors.newfixedThreadPool (3); untuk (int i = 0; i <10; i ++) {indeks int akhir = i; fixedThreadPool.execute (runnable baru () {@Overridepublic void run () {try {System.out.println (index); thread.sleep (2000);} catch (interruptedException e) {// TODO Auto-dihasilkan blok tangkapan e.printstack ();}}};Karena ukuran kumpulan utas adalah 3, tidur 2 detik setelah setiap indeks keluaran tugas, jadi 3 angka dicetak setiap dua detik.
Ukuran kumpulan utas panjang tetap diatur paling sesuai dengan sumber daya sistem. Seperti runtime.getRuntime (). Tersedia Processors (). Silakan merujuk ke preloaddatacache.
(3) NewsCheduledThreadPool:
Buat kumpulan benang panjang tetap yang mendukung eksekusi tugas waktu dan berkala. Kode sampel untuk eksekusi tertunda adalah sebagai berikut:
Terjadwal ExecutorService StorduledThreadPool = Executors.newsCheduledThreadPool (5); JadwalTHreadPool.schedule (runnable baru () {@Overridepublic void run () {System.out.println ("tunda 3 detik");}}, 3, timeunit.seconds);Menunjukkan eksekusi penundaan dengan 3 detik.
Kode sampel dieksekusi secara teratur sebagai berikut:
JadwalThreadPool.scheduleatFixEdrate (runnable baru () {@Overridepublic void run () {System.out.println ("Tunda 1 detik, dan ekskute setiap 3 detik");}}, 1, 3, timeUNIt.seconds);Ini berarti bahwa penundaan dilakukan setiap 3 detik setelah 1 detik.
Terjadwal ExecutorService lebih aman dan lebih kuat dari timer
(4) NewsinglethreadExecutor:
Buat kumpulan utas utas tunggal, yang hanya akan menggunakan utas pekerja yang unik untuk menjalankan tugas, memastikan bahwa semua tugas dieksekusi dalam urutan yang ditentukan (FIFO, LIFO, prioritas). Kode sampel adalah sebagai berikut:
ExecutorService singlethreadExecutor = executors.newsingleThreadExecutor (); for (int i = 0; i <10; i ++) {final int index = i; singlethreadexecutor.execute (new runnable () {@Overridepublic void run () {try {system.out.out.out.out.out.out. (InterruptedException E) {// TODO Auto-Eynerated Catch Block E.PrintStackTrace ();Hasilnya adalah output secara berurutan, yang setara dengan mengeksekusi setiap tugas secara berurutan.
Sebagian besar program GUI saat ini saling berhadapan. Utas tunggal di Android dapat digunakan untuk operasi basis data, operasi file, pemasangan batch aplikasi, penghapusan batch aplikasi, dll., Yang tidak cocok untuk bersamaan tetapi dapat memblokir IO dan mempengaruhi respons utas UI.
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.
Mengapa Menggunakan Thread Pool:
1. Mengurangi berapa kali utas dibuat dan dihancurkan, dan setiap utas pekerja dapat digunakan kembali dan dapat melakukan banyak tugas.
2. Jumlah utas pekerja di kumpulan utas dapat disesuaikan sesuai dengan kemampuan sistem untuk mencegah server dari disedot karena konsumsi memori yang berlebihan (setiap utas membutuhkan sekitar 1MB memori. Semakin banyak utas dibuka, semakin besar memori yang dikonsumsi, dan akhirnya crash akan terjadi.
Antarmuka tingkat atas dari kumpulan utas di Java adalah pelaksana, tetapi secara ketat, pelaksana bukan kumpulan utas, tetapi hanya alat untuk mengeksekusi utas. Antarmuka kumpulan utas nyata adalah ExecutorService.
Beberapa kategori yang lebih penting:
ExecutorService: Antarmuka Pool Thread True.
Terjadwal ExecutorService: Ini bisa mirip dengan timer/timertask, menyelesaikan masalah yang memerlukan tugas berulang.
ThreadPoolExecutor: Implementasi default dari ExecutorService.
TerjadwalThreadPoolExecutor: Implementasi kelas dari Terjadwal ExcecutorService Interface yang mewarisi ThreadPoolExecutor, implementasi kelas penjadwalan tugas berkala.
Cukup rumit untuk mengonfigurasi kumpulan utas, terutama ketika prinsip kumpulan utas tidak terlalu jelas. Sangat mungkin bahwa kumpulan utas yang dikonfigurasi tidak lebih baik. Oleh karena itu, beberapa pabrik statis disediakan di kelas pelaksana untuk menghasilkan beberapa kumpulan benang yang umum digunakan.
1.NewsinglethreadExecutor
Buat kumpulan utas tunggal. Kumpulan utas ini hanya memiliki satu utas yang berfungsi, yang setara dengan satu utas yang melakukan semua tugas dalam serial. Jika utas unik ini berakhir karena pengecualian, maka akan ada utas baru untuk menggantinya. Kumpulan utas ini memastikan bahwa perintah eksekusi semua tugas dieksekusi dalam urutan pengajuan tugas.
2.NewfixedThreadPool
Buat kumpulan utas ukuran tetap. Setiap kali tugas dikirimkan, utas dibuat sampai utas mencapai ukuran maksimum kumpulan utas. Ukuran kumpulan benang tetap sama setelah mencapai nilai maksimumnya. Jika utas berakhir karena pengecualian eksekusi, kumpulan utas akan menambahkan utas baru.
3.NewCachedThreadPool
Buat kumpulan utas yang dapat di -cache. Jika ukuran utas kumpulan melebihi utas yang diperlukan untuk memproses tugas,
Kemudian beberapa utas idle (tidak ada eksekusi tugas dalam 60 detik) akan didaur ulang. Ketika jumlah tugas meningkat, kumpulan utas ini dapat dengan cerdas menambahkan utas baru untuk menangani tugas. Kumpulan utas ini tidak membatasi ukuran kumpulan utas, yang sepenuhnya tergantung pada ukuran utas maksimum yang dapat dibuat oleh sistem operasi (atau JVM).
4.NewsCheduledThreadPool
Buat kumpulan utas dengan ukuran tidak terbatas. Kumpulan utas ini mendukung kebutuhan untuk melakukan tugas secara berkala dan berkala.
Kode contoh
1. Kumpulan utas ukuran tetap, newfixedthreadpool:
paket app.executors; impor java.util.concurrent.Executors; impor java.util.concurrent.executorservice; / ** * Java Thread: Thread Pool * * @Author xiho */ tes kelas publik {public static void main (string [] args) {// Buat kumpulan utas dengan sejumlah tetap utas yang dapat digunakan kembali ExecutorService pool = executors.newfixedThreadpool (2); // Buat utas utas t1 = myThread baru (); Thread t2 = mythread baru (); Thread t3 = mythread baru (); Thread t4 = mythread baru (); Thread t5 = mythread baru (); // Masukkan utas ke kolam untuk eksekusi biliar.Execute (T1); Pool.Execute (T2); Pool.Execute (T3); Pool.Execute (T4); Pool.Execute (T5); // tutup thread pool pool.shutdown (); }} kelas MyThread memperluas utas {@Override public void run () {System.out.println (thread.currentThread (). getName () + "mengeksekusi ..."); }}Hasil output:
Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-3 mengeksekusi. . . Pool-1-Thread-4 mengeksekusi. . . Pool-1-Thread-2 mengeksekusi. . . Pool-1-Thread-5 sedang dieksekusi. . .
Ubah parameter di ExecutorService Pool = Executors.newfixedThreadPool (5): ExecutorService Pool = Executors.newfixedThreadPool (2), dan hasil outputnya adalah:
Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-2 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-2 mengeksekusi. . .
Dari hasil di atas, kita dapat melihat bahwa parameter newfixedthreadpool menentukan jumlah maksimum utas yang dapat dijalankan. Setelah menambahkan lebih dari jumlah utas ini, mereka tidak akan berjalan. Kedua, utas yang ditambahkan ke kumpulan utas berada dalam keadaan yang dikelola, dan operasi utas tidak terpengaruh oleh pesanan bergabung.
2. Pool utas tugas tunggal, NewsLeThreadExecutor:
Cukup ubah pool ExecutorService = executors.newfixedThreadPool (2) dalam kode di atas ke ExecutorService pool = executors.newsinglethreadexecutor ();
Hasil output:
Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-1 mengeksekusi. . .
Dapat dilihat bahwa setiap kali Anda memanggil metode eksekusi, metode run thread-1 sebenarnya dipanggil pada akhirnya.
3. Kolam Benang Ukuran Variabel, NewcachedThreadpool:
Mirip dengan hal di atas, cukup ubah cara kolam dibuat: ExecutorService pool = Executors.newcachedThreadPool ();
Hasil output:
Pool-1-Thread-1 mengeksekusi. . . Pool-1-Thread-2 mengeksekusi. . . Pool-1-Thread-4 mengeksekusi. . . Pool-1-Thread-3 mengeksekusi. . . Pool-1-Thread-5 sedang dieksekusi. . .
Metode ini ditandai dengan fakta bahwa kumpulan utas baru dapat dibuat sesuai kebutuhan, tetapi mereka akan digunakan kembali ketika utas yang dibangun sebelumnya tersedia.
4. Pool Delay Connection, NewsCheduledThreadPool:
tes kelas publikCheduledThreadPoolExecutor {public static void main (string [] args) {scheduledThreadPoolExecutor exec = new DatededThreadPoolExecutor (1); exec.scheduleAtFixedRate (runnable baru () {// Exception dipicu sesekali dalam beberapa saat @Override publicVoid run () {// lempar runimeException baru (); System.out.println ("================================================================================================================ ======================================================================================================================== ======================================================================================================================== ======================================================================================================================== Timeunit.milliseconds);Hasil output:
================= 838464454951683866438290348388643830710 =====================================================================================================================================================================
Di atas adalah semua tentang artikel ini, saya harap ini akan membantu untuk pembelajaran semua orang.