Pembuatan utas Java mahal karena ada sedikit pekerjaan yang harus dilakukan:
- Blok memori yang besar harus dialokasikan dan diinisialisasi untuk tumpukan ulir.
- Panggilan sistem perlu dibuat untuk membuat / mendaftarkan utas asli dengan OS host.
- Deskriptor perlu dibuat, diinisialisasi dan ditambahkan ke struktur data internal JVM.
Ini juga mahal dalam arti bahwa utas mengikat sumber daya selama masih hidup; misal tumpukan ulir, benda apa pun yang dapat dijangkau dari tumpukan, penjelas utas JVM, penjelas utas asli OS.
Biaya semua hal ini adalah platform spesifik, tetapi tidak murah untuk platform Java apa pun yang pernah saya temui.
Pencarian Google menemukan saya patokan lama yang melaporkan tingkat pembuatan utas ~ 4000 per detik pada Sun Java 1.4.1 pada prosesor ganda 2002 Xeon yang menjalankan Linux kuno 2002. Platform yang lebih modern akan memberikan angka yang lebih baik ... dan saya tidak bisa mengomentari metodologi ... tapi setidaknya itu memberikan gambaran kasar tentang seberapa mahal kemungkinan pembuatan utas.
Benchmark Peter Lawrey menunjukkan bahwa pembuatan utas secara signifikan lebih cepat akhir-akhir ini dalam hal absolut, tetapi tidak jelas berapa banyak dari ini karena peningkatan di Jawa dan / atau OS ... atau kecepatan prosesor yang lebih tinggi. Tetapi angka-angkanya masih menunjukkan peningkatan 150+ lipat jika Anda menggunakan kumpulan utas versus membuat / memulai utas baru setiap kali. (Dan dia menekankan bahwa ini semua relatif ...)
(Di atas mengasumsikan "utas asli" daripada "utas hijau", tetapi JVM modern semua menggunakan utas asli untuk alasan kinerja. Utas hijau mungkin lebih murah untuk dibuat, tetapi Anda membayarnya di area lain.)
Saya telah melakukan sedikit penggalian untuk melihat bagaimana tumpukan Java thread benar-benar dialokasikan. Dalam kasus OpenJDK 6 di Linux, tumpukan thread dialokasikan oleh panggilan ke pthread_create
yang membuat utas asli. (JVM tidak melewati pthread_create
tumpukan yang telah dialokasikan sebelumnya.)
Kemudian, di pthread_create
dalam stack dialokasikan oleh panggilan ke mmap
sebagai berikut:
mmap(0, attr.__stacksize,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
Menurutnya man mmap
, MAP_ANONYMOUS
flag menyebabkan memori diinisialisasi ke nol.
Dengan demikian, meskipun mungkin tidak penting bahwa tumpukan ulir Java baru dipusatkan (sesuai spesifikasi JVM), dalam praktiknya (setidaknya dengan OpenJDK 6 di Linux), tumpukan ini nol.