ThreadPoolExecutor - 1

"Pengaturcara biasa lambat laun akan memahami hakikat bahawa mereka mempunyai banyak tugas kecil yang perlu dilakukan dari semasa ke semasa."

"Jika anda menulis permainan, maka itu adalah tindakan yang dilakukan oleh watak individu."

"Jika anda menulis pelayan web, maka ia adalah arahan berbeza yang datang daripada pengguna: muat naik foto, transkodkannya ke dalam format yang diingini, gunakan templat yang dikehendaki, dsb."

"Lambat laun, semua tugas besar dipecahkan kepada satu set tugas yang kecil dan boleh diurus."

"Jadi, memandangkan konteks ini, persoalan halus timbul: bagaimana anda sepatutnya mengurus semuanya? Bagaimana jika anda perlu melaksanakan beberapa ratus tugasan dalam satu minit? Mencipta benang untuk setiap tugasan tidak akan masuk akal. Mesin Java memperuntukkan banyak sumber untuk setiap utas."

"Dengan kata lain, mencipta dan memusnahkan utas mungkin mengambil lebih banyak masa dan sumber daripada tugas itu sendiri."

"Pencipta Java datang dengan penyelesaian yang elegan untuk masalah ini: ThreadPoolExecutor .

" ThreadPoolExecutor ialah kelas dengan dua perkara di dalamnya:"

A)  Barisan tugasan, yang boleh anda tambahkan tugasan apabila ia timbul dalam program.

B) Kumpulan benang, iaitu kumpulan benang yang melaksanakan tugasan ini.

"Apatah lagi, benang tidak dimusnahkan sebaik sahaja tugasan selesai. Sebaliknya, ia tertidur untuk bersedia untuk memulakan tugasan baharu sebaik sahaja tugasan itu muncul."

"Apabila anda mencipta ThreadPoolExecutor , anda boleh menetapkan bilangan maksimum utas untuk dibuat dan bilangan maksimum tugasan yang boleh beratur. Dengan kata lain, anda boleh mengehadkan bilangan utas kepada 10, sebagai contoh, dan bilangan tugas beratur kepada 100."

"Beginilah cara ThreadPoolExecutor berfungsi:"

1)  Apabila anda menambah tugasan baharu, ia diletakkan di hujung baris gilir.

2)  Jika baris gilir penuh, pengecualian akan dilemparkan.

3)  Setelah menyelesaikan tugas, setiap utas mengambil tugas seterusnya dari baris gilir dan mula melaksanakannya.

4) Jika tiada tugasan dalam baris gilir, benang akan tidur sehingga tugasan baharu ditambahkan.

"Pendekatan, di mana kita mengehadkan bilangan benang pekerja, adalah berfaedah kerana lebih banyak benang yang kita miliki, lebih banyak ia mengganggu antara satu sama lain. Ia adalah lebih berkesan untuk mempunyai 5-10 benang pekerja dan barisan tugas yang panjang daripada untuk mencipta 100 utas untuk lonjakan tugas, yang akan bersaing antara satu sama lain untuk sumber: memori, masa pemproses, akses pangkalan data, dll."

"Berikut ialah contoh ThreadPoolExecutor dalam tindakan:"

Contoh
ExecutorService service = Executors.newFixedThreadPool(2);

for(int i = 0; i < 10; i++)
{
 service.submit(new Runnable() {
    public void run()
    {
     // Here we download something big from the Internet.
    }
 });
}

"Eh, saya tak nampak…"

" Objek ThreadPoolExecutor dicipta apabila kaedah newFixedThreadPool dipanggil."

Jadi, ia sangat mudah untuk digunakan. Sebaik sahaja anda menambah tugasan padanya dengan kaedah serah, ia:

A)  Membangunkan benang tidur, jika ada, untuk melaksanakan tugas.

B)  Jika tiada utas menunggu, maka ia mencipta benang baharu untuk tugas itu.

C)  Jika bilangan maksimum benang dicapai, maka ia hanya meletakkan tugas di penghujung baris gilir.

"Saya sengaja memasukkan «di sini kami memuat turun sesuatu yang besar dari Internet» dalam contoh. Jika kami mempunyai 100 tugas «muat turun sesuatu yang besar daripada Internet», maka tidak masuk akal untuk menjalankan banyak tugasan pada masa yang sama—kami' akan ditahan oleh had lebar jalur sambungan Internet kami. Dalam kes ini, beberapa utas sepatutnya mencukupi. Inilah yang anda lihat dalam contoh di atas:"

ExecutorService service = Executors.newFixedThreadPool(2);

"Ternyata bekerja dengan banyak tugas tidaklah begitu sukar."

"Ya. Malah lebih mudah daripada yang anda bayangkan. Tetapi Kim akan memberitahu anda tentang itu."