Jebakan: Pinning dan ThreadLocals
Hindari pemblokiran thread pembawa.
Jebakan: Pinning dan ThreadLocals adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.
Hal-Hal yang Dapat Menjadi Masalah
Utas virtual sangat kuat, tetapi dua kendala dapat diam-diam merusak skalabilitasnya: keterpakuan dan penggunaan ThreadLocals secara berlebihan.
Pelajaran ini menjelaskan keduanya dan cara menghindarinya.
Apa Itu Keterpakuan
Keterpakuan terjadi ketika utas virtual tidak dapat melepaskan diri dari utas pembawanya saat terblokir. Utas OS pembawa tetap macet, sehingga manfaat skalabilitasnya hilang.
Jika terlalu banyak utas pembawa terpaku, kapasitas pemrosesan akan runtuh.
Penyebab: Pemblokiran Tersinkronisasi
Penyebab klasiknya adalah pemblokiran di dalam blok atau metode synchronized. Saat memegang monitor lalu terblokir, utas virtual tetap terpaku pada utas pembawanya.
Catatan: pada JDK 24+ (JEP 491), keterbatasan ini sebagian besar telah dihapus, tetapi pada Java 21 hal ini masih menjadi perhatian nyata.
Contoh Keterpakuan yang Harus Dihindari
Pola ini dapat menyebabkan keterpakuan pada Java 21: memblokir saat memegang monitor. Kode tersebut tetap berjalan dengan benar, tetapi tidak dapat diskalakan.
public class Main {
static final Object lock = new Object();
static void risky() {
synchronized (lock) {
try { Thread.sleep(10); } catch (InterruptedException e) {}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = Thread.ofVirtual().start(Main::risky);
t.join();
System.out.println("Done (but this blocked inside synchronized)");
}
}Perbaikan: ReentrantLock
Ganti synchronized dengan ReentrantLock ketika bagian kritis mungkin terblokir. API penguncian ramah terhadap utas virtual dan memungkinkan pelepasan utas pembawa.
import java.util.concurrent.locks.ReentrantLock;
public class Main {
static final ReentrantLock lock = new ReentrantLock();
static void safe() {
lock.lock();
try {
try { Thread.sleep(10); } catch (InterruptedException e) {}
} finally {
lock.unlock();
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = Thread.ofVirtual().start(Main::safe);
t.join();
System.out.println("Done without pinning");
}
}Mendiagnosis Keterpakuan
Anda dapat meminta JVM mencetak jejak tumpukan setiap kali terjadi keterpakuan dengan menjalankan program menggunakan:
-Djdk.tracePinnedThreads=fulluntuk jejak lengkap-Djdk.tracePinnedThreads=shortuntuk satu baris
Hal ini membantu Anda menemukan bagian synchronized yang bermasalah.
ThreadLocals Menjadi Mahal
ThreadLocal menyimpan status per utas. Dengan beberapa utas platform, hal itu tidak masalah. Dengan jutaan utas virtual, yang masing-masing membawa salinannya sendiri, penggunaan memori membengkak.
Periksa pustaka Anda: penyimpanan, pemformatan, dan objek konteks sering kali menyembunyikan ThreadLocals.
ThreadLocal Tetap Berfungsi
ThreadLocal tidak dilarang, tetapi gunakan secukupnya. Setiap utas virtual mendapatkan nilainya sendiri seperti yang diharapkan.
public class Main {
static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
Thread t = Thread.ofVirtual().start(() -> {
CONTEXT.set("request-42");
System.out.println("Context: " + CONTEXT.get());
CONTEXT.remove();
});
t.join();
}
}Pilih ScopedValue
Java memperkenalkan ScopedValue sebagai alternatif yang lebih ringan untuk berbagi data yang tidak dapat diubah dengan masa hidup terbatas. Cara ini menghindari biaya penyimpanan yang dapat berubah per utas dari ThreadLocal dan sesuai dengan model konkurensi terstruktur.
Jika Anda hanya perlu meneruskan konteks hanya-baca ke sepanjang rantai pemanggilan, gunakanlah ini.
Jangan Mengumpulkan Utas
Kendala lain yang tidak kentara adalah memperlakukan utas virtual seperti sumber daya langka lalu mengumpulkannya. Hal itu mengembalikan persaingan dan kebocoran ThreadLocal di antara tugas.
Selalu buat satu utas virtual untuk setiap tugas dan biarkan utas tersebut berhenti.
Daftar Periksa Skalabilitas
Sebelum menggunakan utas virtual dalam produksi:
- Ganti
synchronizedyang memblokir denganReentrantLock - Aktifkan
jdk.tracePinnedThreadssaat pengujian - Minimalkan penggunaan
ThreadLocal; pilihScopedValue - Jangan pernah mengumpulkan utas virtual
Uji Singkat
Identifikasi pengganti yang aman untuk blok tersinkronisasi yang memblokir.
Rangkuman
Anda telah mempelajari kendala utamanya:
- Keterpakuan: pemblokiran di dalam
synchronizedmenyibukkan utas pembawa; perbaiki denganReentrantLock - Diagnosis dilakukan dengan
-Djdk.tracePinnedThreads - Overhead ThreadLocal meningkat seiring jumlah utas; pilih
ScopedValue - Jangan pernah mengumpulkan utas virtual
Dengan demikian, kursus Utas Virtual telah selesai.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Jebakan: Pinning dan ThreadLocals” gratis?
Ya — teks lengkap “Jebakan: Pinning dan ThreadLocals” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Jebakan: Pinning dan ThreadLocals”?
Hindari pemblokiran thread pembawa. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Java Academy?
Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Jebakan: Pinning dan ThreadLocals” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Apa Itu Virtual Thread
- Membuat Virtual Thread
- Thread Platform vs Virtual
- Jebakan: Pinning dan ThreadLocals