0Pricing
Java Academy · Pelajaran

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=full untuk jejak lengkap
  • -Djdk.tracePinnedThreads=short untuk 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 synchronized yang memblokir dengan ReentrantLock
  • Aktifkan jdk.tracePinnedThreads saat pengujian
  • Minimalkan penggunaan ThreadLocal; pilih ScopedValue
  • 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 synchronized menyibukkan utas pembawa; perbaiki dengan ReentrantLock
  • 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

  1. Apa Itu Virtual Thread
  2. Membuat Virtual Thread
  3. Thread Platform vs Virtual
  4. Jebakan: Pinning dan ThreadLocals
← Kembali ke Java Academy