Perangkap: Pinning dan ThreadLocals
Elakkan menyekat thread pembawa
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=fulluntuk jejak penuh-Djdk.tracePinnedThreads=shortuntuk 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
synchronizedyang menyekat denganReentrantLock - Aktifkan
jdk.tracePinnedThreadssemasa pengujian - Kurangkan penggunaan
ThreadLocal; utamakanScopedValue - 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
synchronizedmengikat benang pembawa; baiki denganReentrantLock - Diagnosis menggunakan
-Djdk.tracePinnedThreads - Overhed ThreadLocal meningkat mengikut bilangan benang; utamakan
ScopedValue - Jangan kumpulkan benang maya
Dengan ini, kursus Benang Maya selesai.
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
- Apakah Thread Maya
- Mencipta Thread Maya
- Thread Platform berbanding Thread Maya
- Perangkap: Pinning dan ThreadLocals