Katakanlah saya memiliki aplikasi yang menggunakan Executor
kerangka kerja seperti itu
Executors.newSingleThreadExecutor().submit(new Runnable(){
@Override
public void run(){
// do stuff
}
}
Ketika saya menjalankan aplikasi ini di debugger, thread dibuat dengan berikut (default) Nama: Thread[pool-1-thread-1]
. Seperti yang Anda lihat, ini tidak terlalu berguna dan sejauh yang saya tahu, Executor
framework tidak memberikan cara yang mudah untuk memberi nama thread yang dibuat atau pool-thread.
Jadi, bagaimana cara menyediakan nama untuk utas / utas? Misalnya Thread[FooPool-FooThread]
,.
Anda dapat mencoba menyediakan pabrik utas sendiri, yang akan membuat utas dengan nama yang sesuai. Ini salah satu contohnya:
sumber
Anda juga dapat mengubah nama utas setelahnya, saat utas dijalankan:
Itu bisa menarik jika misalnya Anda menggunakan ThreadFactory yang sama untuk berbagai jenis tugas.
sumber
(Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.)
. Jika ExecutorService mengganti utas, itu akan dinamai oleh ThreadFactory. Kemudian lagi, melihat nama menghilang saat debugging bisa menjadi indikator yang berguna.The
BasicThreadFactory
dari apache commons-lang juga berguna untuk menyediakan perilaku penamaan. Alih-alih menulis kelas dalam anonim, Anda dapat menggunakan Builder untuk memberi nama utas yang Anda inginkan. Inilah contoh dari javadocs:sumber
Jika Anda menggunakan Spring, ada
CustomizableThreadFactory
yang Anda dapat mengatur awalan nama utas.Contoh:
Atau, Anda bisa membuatnya
ExecutorService
menggunakan kacang Spring menggunakanThreadPoolExecutorFactoryBean
- maka semua utas akan dinamai denganbeanName-
awalan.Pada contoh di atas, utas akan diberi nama dengan
myExecutor-
awalan. Anda dapat mengatur awalan secara eksplisit ke nilai yang berbeda (mis."myPool-"
) Dengan menyetelexecutorFactoryBean.setThreadNamePrefix("myPool-")
pada kacang pabrik.sumber
Ada RFE terbuka untuk ini dengan Oracle. Dari komentar dari karyawan Oracle tampaknya mereka tidak mengerti masalah ini dan tidak akan memperbaiki. Ini adalah salah satu dari hal-hal ini yang sangat sederhana untuk didukung di JDK (tanpa melanggar kompatibilitas ke belakang) sehingga agak memalukan bahwa RFE disalahpahami.
Seperti yang ditunjukkan, Anda perlu mengimplementasikan ThreadFactory Anda sendiri . Jika Anda tidak ingin menarik Guava atau Apache Commons hanya untuk tujuan ini saya berikan di sini
ThreadFactory
implementasi yang dapat Anda gunakan. Ini persis sama dengan apa yang Anda dapatkan dari JDK kecuali untuk kemampuan untuk mengatur awalan nama utas ke sesuatu yang lain selain "kumpulan".Ketika Anda ingin menggunakannya, Anda cukup memanfaatkan fakta bahwa semua
Executors
metode memungkinkan Anda untuk menyediakannya sendiriThreadFactory
.Ini
akan memberikan ExecutorService di mana utas diberi nama
pool-N-thread-M
tetapi dengan menggunakanAnda akan mendapatkan ExecutorService di mana utas diberi nama
primecalc-N-thread-M
. Voila!sumber
ThreadGroup
mendukungThreadPoolExecutor
.Lewati ThreadFactory ke layanan eksekutor dan Anda siap melakukannya
sumber
Cara cepat dan kotor adalah dengan menggunakan
Thread.currentThread().setName(myName);
dirun()
metode.sumber
Perpanjang ThreadFactory
public interface ThreadFactory
Thread newThread(Runnable r)
Kode sampel:
keluaran:
.... dll
sumber
Seperti yang sudah dijawab oleh jawaban lain, Anda dapat membuat dan menggunakan implementasi
java.util.concurrent.ThreadFactory
antarmuka Anda sendiri (tidak perlu pustaka eksternal). Saya menempelkan kode saya di bawah karena berbeda dari jawaban sebelumnya karena menggunakanString.format
metode dan mengambil nama dasar untuk utas sebagai argumen konstruktor:Dan ini adalah contoh penggunaan:
EDIT : membuat
ThreadFactory
implementasi saya aman, terima kasih kepada @mchernyakov karena menunjukkannya.Meskipun tidak ada dalam
ThreadFactory
dokumentasi yang mengatakan bahwa implementasinya harus aman-utas, fakta bahwaDefaultThreadFactory
aman-utas adalah petunjuk besar:sumber
Solusi Java inti yang dikembangkan sendiri yang saya gunakan untuk menghias pabrik yang ada:
Beraksi:
sumber
sumber
Anda dapat menulis implementasi ThreadFactory Anda sendiri, menggunakan misalnya beberapa implementasi yang ada (seperti defaultThreadFactory) dan mengubah nama di akhir.
Contoh penerapan ThreadFactory:
Dan penggunaan:
sumber
Saya menggunakan untuk melakukan hal yang sama seperti di bawah ini (memerlukan
guava
perpustakaan):sumber
ThreadFactoryBuilder
itu dari perpustakaan Google Guava.Saya merasa paling mudah untuk menggunakan lambda sebagai pabrik utas jika Anda hanya ingin mengubah nama untuk satu pelaksana utas.
sumber
main@1, Finalizer@667, Reference Handler@668, Your name@665, Signal Dispatcher@666
Ini adalah pabrik saya yang disesuaikan yang menyediakan nama yang disesuaikan untuk analisis penampung ulir. Biasanya saya hanya memberikan
tf=null
untuk menggunakan kembali pabrik thread JVM default. Situs web ini memiliki pabrik utas yang lebih canggih.Untuk kenyamanan Anda, ini adalah loop dump thread untuk tujuan debug.
sumber