Saya memiliki program yang memunculkan utas (~ 5-150) yang melakukan banyak tugas. Awalnya, saya menggunakan FixedThreadPool
karena pertanyaan serupa ini menyarankan mereka lebih cocok untuk tugas yang berumur lebih lama dan dengan pengetahuan saya yang sangat terbatas tentang multithreading, saya menganggap rata-rata umur utas (beberapa menit) " berumur panjang ".
Namun, saya baru-baru ini menambahkan kemampuan untuk menelurkan utas tambahan dan melakukannya membawa saya di atas batas utas yang saya tetapkan. Dalam hal ini, apakah lebih baik menebak dan menambah jumlah utas yang dapat saya izinkan atau beralih ke CachedThreadPool
jadi saya tidak memiliki utas yang terbuang?
Mencoba mereka berdua keluar preliminarily, ada tidak tampaknya menjadi perbedaan jadi aku cenderung untuk pergi dengan CachedThreadPool
hanya untuk menghindari sampah. Namun, apakah rentang hidup utas berarti saya harus memilih FixedThreadPool
dan hanya menangani utas yang tidak digunakan? Pertanyaan ini membuatnya tampak seperti utas ekstra itu tidak sia-sia, tetapi saya akan menghargai klarifikasi.
ThreadPoolExecutor
like yang dibatasiThreadPoolExecutor(0, maximumPoolSize, 60L, TimeUnit.SECONDS, SynchronousQueue())
?Kedua
FixedThreadPool
danCachedThreadPool
yang jahat dalam aplikasi yang sangat dimuat.CachedThreadPool
lebih berbahaya dariFixedThreadPool
Jika aplikasi Anda sangat dimuat & menuntut latensi rendah, lebih baik hilangkan kedua opsi karena kekurangan di bawah ini
CachedThreadPool
lepas kendali pada pembuatan ThreadKarena Anda tahu bahwa keduanya adalah kejahatan, kejahatan yang lebih kecil tidak ada gunanya. Lebih suka ThreadPoolExecutor , yang menyediakan kontrol terperinci pada banyak parameter.
beforeExecute(Thread, Runnable)
danafterExecute(Runnable, Throwable)
sumber
Apakah Anda yakin Anda memahami bagaimana utas sebenarnya diproses oleh OS dan perangkat keras pilihan Anda? Bagaimana Java memetakan utas ke utas OS, bagaimana memetakan utas ke utas CPU, dll.? Saya bertanya karena membuat 150 utas di dalam SATU JRE hanya masuk akal jika Anda memiliki inti / utas CPU yang besar di bawahnya, yang kemungkinan besar tidak demikian. Bergantung pada OS dan RAM yang digunakan, membuat lebih dari n utas bahkan dapat mengakibatkan JRE Anda dihentikan karena kesalahan OOM. Jadi, Anda harus benar-benar membedakan antara utas dan pekerjaan yang harus dilakukan oleh utas itu, berapa banyak pekerjaan yang bahkan dapat Anda proses, dll.
Dan itulah masalah dengan CachedThreadPool: Tidak masuk akal untuk mengantri pekerjaan yang berjalan lama di utas yang sebenarnya tidak dapat berjalan karena Anda hanya memiliki 2 inti CPU yang dapat memproses utas tersebut. Jika Anda berakhir dengan 150 utas terjadwal, Anda mungkin membuat banyak overhead yang tidak perlu untuk penjadwal yang digunakan dalam Java dan OS untuk memprosesnya secara bersamaan. Ini tidak mungkin dilakukan jika Anda hanya memiliki 2 inti CPU, kecuali utas Anda menunggu I / O atau semacamnya sepanjang waktu. Tetapi bahkan dalam kasus itu banyak utas akan membuat banyak I / O ...
Dan masalah itu tidak terjadi dengan FixedThreadPool, yang dibuat dengan misalnya 2 + n utas, di mana n tentu saja cukup rendah, karena dengan perangkat keras dan sumber daya OS digunakan dengan overhead yang jauh lebih sedikit untuk mengelola utas yang tetap tidak dapat berjalan.
sumber