Saat mengembangkan aplikasi multi-utas, biasanya kita harus berurusan dengan pengorganisasian pekerjaan utas. Semakin besar aplikasi kita dan semakin banyak utas yang kita butuhkan untuk tugas multithread, semakin banyakDapat dijalankanobjek yang kita buat.

Perlu dicatat di sini bahwa membuat utas di Java adalah operasi yang agak mahal. Jika kami membuat instance baru dari utas setiap kali melakukan operasi, kami akan mendapatkan masalah besar dengan kinerja dan, akibatnya, dengan kesehatan aplikasi.

Kumpulan utas dan ThreadPoolExecutor membantu kami di sini.

Kumpulan utas adalah kumpulan utas yang telah diinisialisasi sebelumnya. Ukurannya bisa tetap atau variabel.

Jika ada lebih banyak tugas daripada utas, maka tugas akan menunggu dalam antrean tugas. Utas ke-N di kumpulan mengambil tugas dari antrean, dan setelah selesai, utas mengambil tugas baru dari antrean. Setelah semua tugas dalam antrean dijalankan, utas tetap aktif dan menunggu tugas baru. Saat tugas baru muncul, utas juga mulai menjalankannya.

ThreadPoolExecutor

Dimulai dengan Java 5, framework Executor memperoleh solusi multithreading. Secara umum, ini memiliki banyak komponen dan tujuannya adalah untuk membantu kami mengelola antrean dan kumpulan utas secara efisien.

Antarmuka utamanya adalah Executor dan ExecutorService .

Pelaksana adalah antarmuka dengan metode eksekusi tunggal (Runnable runnable).

Saat meneruskan tugas ke implementasi metode ini, ketahuilah bahwa itu akan dieksekusi secara asinkron di masa mendatang.

ExecutorService — Antarmuka yang memperluas antarmuka Pelaksana , menambahkan kemampuan untuk menjalankan tugas. Ini juga memiliki metode untuk menghentikan tugas yang sedang berjalan dan menghentikan kumpulan utas.

ThreadPoolExecutor mengimplementasikan antarmuka Executor dan ExecutorService dan memisahkan pembuatan tugas dari eksekusi tugas. Kita perlu mengimplementasikan objek Runnable dan mengirimkannya ke eksekutor. ThreadPoolExecutorkemudian bertanggung jawab menjalankan tugas, dan membuat serta bekerja dengan utas .

Setelah tugas dikirim untuk dieksekusi, utas yang ada di kumpulan digunakan. Ini meningkatkan kinerja. Ini memecahkan masalah pemborosan sumber daya untuk membuat dan menginisialisasi utas baru, dan sekali lagi pada pengumpulan sampah setelah kita selesai dengan utas.

ThreadPoolExecutor memiliki 4 konstruktor:


ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit, 
BlockingQueue<Runnable> workQueue)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory)
    

ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime, 
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory, 
RejectedExecutionHandler handler)
    

Konstruktor ThreadPoolExecutor memiliki parameter berikut:

corePoolSize Parameter ini menunjukkan berapa banyak utas yang akan siap (dimulai) saat layanan pelaksana dimulai.
maximumPoolSize Jumlah maksimum utas yang dapat dibuat oleh layanan eksekutor.
keepAliveTime Waktu utas yang dibebaskan akan terus hidup sebelum dihancurkan jika jumlah utas lebih besar daricorePoolSize. Satuan waktu ditentukan dalam parameter berikutnya.
satuan Satuan waktu (jam, menit, detik, milidetik, dll.).
workQueue Implementasi antrian untuk tugas.
pawang Penangan untuk tugas yang tidak dapat diselesaikan.
threadFactory Objek yang membuat utas baru sesuai permintaan. Menggunakan pabrik utas membuat panggilan ke perangkat keras utas baru secara independen, memungkinkan aplikasi untuk menggunakan subkelas utas khusus, prioritas, dan sebagainya.

Membuat ThreadPoolExecutor

Kelas utilitas Pelaksana dapat menyederhanakan pembuatan ThreadPoolExecutor . Metode kelas utilitas ini membantu kita mempersiapkan aThreadPoolExecutorobyek.

newFixedThreadPool — Membuat kumpulan utas yang menggunakan kembali utas dalam jumlah tetap untuk menjalankan sejumlah tugas.

ExecutorService executor = Executors.newFixedThreadPool(10);
                    
newWorkStealingPool — Membuat kumpulan utas di mana jumlah utas sama dengan jumlah inti prosesor yang tersedia untuk JVM. Level konkurensi default adalah satu. Ini berarti bahwa banyak utas akan dibuat di kumpulan karena ada inti CPU yang tersedia untuk JVM. Jika level konkurensi adalah 4, maka nilai yang diteruskan digunakan sebagai pengganti jumlah inti.

ExecutorService executor = Executors.newWorkStealingPool(4);
                    
newSingleThreadExecutor — Membuat kumpulan dengan satu utas untuk menjalankan semua tugas.

ExecutorService executor = Executors.newSingleThreadExecutor();
                    
newCachedThreadPool — Membuat kumpulan utas yang membuat utas baru sesuai kebutuhan, tetapi menggunakan kembali utas yang dibuat sebelumnya saat tersedia.

ExecutorService executor = Executors.newCachedThreadPool();
                    
newScheduledThreadPool — Membuat kumpulan utas yang dapat menjadwalkan perintah untuk dijalankan setelah penundaan tertentu atau secara berkala.

ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
                    

Kami akan mempertimbangkan setiap jenis kolam dalam pelajaran berikut.