Java Academy · Pelajaran

Perangkap: Pinning dan ThreadLocals

Elakkan menyekat thread pembawa

Pelajaran 4 daripada 413 langkah

Perangkap: Pinning dan ThreadLocals ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Perkara yang Boleh Menjadi Salah

Benang maya berkuasa, tetapi dua perangkap boleh menjejaskan kebolehskalaannya tanpa disedari: pengikatan dan penggunaan berlebihan ThreadLocals.

Pelajaran ini menerangkan kedua-duanya serta cara mengelakkannya.

Apakah Pengikatan

Pengikatan berlaku apabila benang maya tidak boleh dinyahpasang daripada benang pembawanya semasa disekat. Benang OS pembawa kekal tersekat, sekali gus menafikan manfaat kebolehskalaan.

Apabila terlalu banyak benang pembawa terikat, daya pemprosesan merosot dengan teruk.

Punca: Sekatan Disegerakkan

Punca klasiknya ialah penyekatan di dalam blok atau kaedah synchronized. Apabila memegang pemantau lalu disekat, benang maya kekal terikat pada benang pembawanya.

Nota: dalam JDK 24+ (JEP 491), had ini sebahagian besarnya telah dialih keluar, tetapi dalam Java 21 ia masih merupakan kebimbangan sebenar.

Contoh Pengikatan yang Perlu Dielakkan

Pola ini boleh menyebabkan pengikatan dalam Java 21: penyekatan semasa memegang pemantau. Kod ini masih berjalan dengan betul, tetapi tidak boleh 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)");
    }
}

Penyelesaian: ReentrantLock

Gantikan synchronized dengan ReentrantLock apabila bahagian kritikal mungkin disekat. Antara muka kunci mesra benang maya dan membenarkan nyahpemasangan.

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 Pengikatan

Anda boleh meminta JVM mencetak jejak tindanan setiap kali pengikatan berlaku dengan melancarkan program menggunakan:

  • -Djdk.tracePinnedThreads=full untuk jejak penuh
  • -Djdk.tracePinnedThreads=short untuk jejak satu baris

Ini membantu anda mencari bahagian synchronized yang bermasalah.

ThreadLocals Menjadi Mahal

ThreadLocal menyimpan keadaan bagi setiap benang. Dengan beberapa benang platform, perkara itu tidak menjadi masalah. Dengan jutaan benang maya yang setiap satunya membawa salinan sendiri, penggunaan memori meningkat dengan mendadak.

Periksa pustaka anda: penyimpanan sementara, pemformatan dan objek konteks sering menyembunyikan ThreadLocals.

ThreadLocal Masih Berfungsi

ThreadLocal tidak dilarang, cuma gunakannya secara berhemat. Setiap benang maya mendapat nilainya sendiri seperti yang dijangkakan.

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();
    }
}

Utamakan ScopedValue

Java memperkenalkan ScopedValue sebagai alternatif yang lebih ringan untuk berkongsi data tidak berubah dengan jangka hayat terhad. Ia mengelakkan kos storan boleh ubah bagi setiap benang yang diperlukan oleh ThreadLocal dan sesuai dengan model keserentakan berstruktur.

Jika anda hanya perlu menghantar konteks baca sahaja sepanjang rantaian panggilan, pilihlahnya.

Jangan Kumpulkan

Satu lagi perangkap yang halus ialah menganggap benang maya sebagai sumber terhad lalu mengumpulkannya. Tindakan itu memperkenalkan semula persaingan dan kebocoran ThreadLocal antara tugas.

Sentiasa cipta satu benang maya bagi setiap tugas dan biarkan benang itu tamat.

Senarai Semak untuk Kebolehskalaan

Sebelum menggunakan benang maya dalam persekitaran pengeluaran:

  • Gantikan synchronized yang menyekat dengan ReentrantLock
  • Aktifkan jdk.tracePinnedThreads semasa pengujian
  • Kurangkan penggunaan ThreadLocal; utamakan ScopedValue
  • Jangan kumpulkan benang maya

Semakan Pantas

Kenal pasti pengganti yang selamat untuk blok disegerakkan yang menyekat.

Ringkasan

Anda telah mempelajari perangkap utama:

  • Pengikatan: penyekatan di dalam synchronized mengikat benang pembawa; baiki dengan ReentrantLock
  • Diagnosis menggunakan -Djdk.tracePinnedThreads
  • Overhed ThreadLocal meningkat mengikut bilangan benang; utamakan ScopedValue
  • Jangan kumpulkan benang maya

Dengan ini, kursus Benang Maya selesai.

Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
104
Pelajaran
374

Soalan Lazim

Adakah pelajaran “Perangkap: Pinning dan ThreadLocals” percuma?

Ya — teks penuh “Perangkap: Pinning dan ThreadLocals” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Perangkap: Pinning dan ThreadLocals”?

Elakkan menyekat thread pembawa Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Java Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Perangkap: Pinning dan ThreadLocals” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Apakah Thread Maya
  2. Mencipta Thread Maya
  3. Thread Platform berbanding Thread Maya
  4. Perangkap: Pinning dan ThreadLocals
← Kembali ke Java Academy