Tuzaklar: Sabitleme ve ThreadLocals
Taşıyıcı iş parçacıklarını engellemekten kaçının
Tuzaklar: Sabitleme ve ThreadLocals, CoddyKit'te ücretsiz bir Java Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Java Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Java Academy kursu toplamda 4 dersten oluşur.
Ortaya Çıkabilecek Sorunlar
Sanal iş parçacıkları güçlüdür, ancak iki sorun ölçeklenebilirliklerini fark edilmeden zayıflatabilir: sabitleme ve ThreadLocals'ın aşırı kullanımı.
Bu derste her ikisi ve bunlardan kaçınma yolları açıklanmaktadır.
Sabitleme Nedir
Sabitleme, bir sanal iş parçacığının engellendiği sırada taşıyıcısından ayrılamaması durumunda gerçekleşir. Taşıyıcı OS iş parçacığı takılı kalır ve ölçeklenebilirlik avantajı ortadan kalkar.
Çok fazla taşıyıcı sabitlendiğinde iş hacmi çöker.
Neden: Senkronize Bölümde Engelleme
Klasik neden, bir synchronized bloğunun veya yönteminin içinde engelleme gerçekleşmesidir. Monitörü tutarken engelleme yapan sanal iş parçacığı taşıyıcısına sabitlenmiş olarak kalır.
Not: JDK 24+ sürümünde (JEP 491) bu sınırlama büyük ölçüde kaldırılmıştır, ancak Java 21'de gerçek bir endişe olmaya devam eder.
Kaçınılması Gereken Sabitleme Örneği
Bu kalıp Java 21'de sabitlemeye neden olabilir: bir monitörü tutarken engelleme yapmak. Kod yine doğru çalışır, ancak ölçeklenmez.
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)");
}
}Çözüm: ReentrantLock
Kritik bölüm engellenebilecekse synchronized yerine ReentrantLock kullanın. Kilit arayüzleri sanal iş parçacıklarıyla uyumludur ve ayırmaya izin verir.
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");
}
}Sabitlemeyi Teşhis Etme
Sabitleme gerçekleştiğinde yığın izini yazdırması için JVM'ye, şu seçenekle başlatarak talimat verebilirsiniz:
- Tam izler için
-Djdk.tracePinnedThreads=full - Tek satırlık izler için
-Djdk.tracePinnedThreads=short
Bu, soruna neden olan synchronized bölümleri bulmanıza yardımcı olur.
ThreadLocals Pahalı Hale Geliyor
ThreadLocal, iş parçacığı başına durum saklar. Birkaç platform iş parçacığıyla bu sorun oluşturmaz. Kendi kopyasını taşıyan milyonlarca sanal iş parçacığı olduğunda bellek şişer.
Kitaplıklarınızı inceleyin: önbelleğe alma, biçimlendirme ve bağlam nesneleri çoğu zaman ThreadLocals kullanımını gizler.
ThreadLocal Hâlâ Çalışır
ThreadLocal yasak değildir; yalnızca ölçülü kullanın. Her sanal iş parçacığı, beklendiği gibi kendi değerini alır.
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();
}
}ScopedValue Tercih Edin
Java, değişmez verileri sınırlı bir ömürle paylaşmak için daha hafif bir seçenek olarak ScopedValue sundu. Bu seçenek, ThreadLocal için iş parçacığı başına değiştirilebilir depolama maliyetini ortadan kaldırır ve yapılandırılmış eşzamanlılık modeliyle uyumludur.
Yalnızca salt okunur bir bağlamı çağrı zincirinde aşağıya aktarmanız gerektiğinde bunun yerine onu tercih edin.
Havuzlamayın
Bir başka ince sorun da sanal iş parçacıklarını kıt bir kaynakmış gibi ele alıp havuzlamaktır. Bu, görevler arasında çekişmeyi ve ThreadLocal değerlerinin sızmasını yeniden ortaya çıkarır.
Her zaman görev başına bir sanal iş parçacığı oluşturun ve sonlanmasına izin verin.
Ölçeklendirme Kontrol Listesi
Sanal iş parçıklarıyla üretime geçmeden önce:
- Engelleyici
synchronizedyapısınıReentrantLockile değiştirin - Sınama sırasında
jdk.tracePinnedThreadsözelliğini etkinleştirin ThreadLocalkullanımını en aza indirin;ScopedValue'yu tercih edin- Sanal iş parçacıklarını asla havuzlamayın
Hızlı Kontrol
Engelleme yapan bir synchronized bloğu için güvenli değişikliği belirleyin.
Özet
Temel sorunları öğrendiniz:
- Sabitleme:
synchronizediçindeki engelleme bir taşıyıcıyı meşgul eder;ReentrantLockile düzeltilir -Djdk.tracePinnedThreadsile teşhis edilir- ThreadLocal ek yükü iş parçacığı sayısıyla birlikte artar;
ScopedValue'yu tercih edin - Sanal iş parçacıklarını asla havuzlamayın
Bu, Sanal İş Parçacıkları kursunu tamamlar.
Sıkça Sorulan Sorular
“Tuzaklar: Sabitleme ve ThreadLocals” dersi ücretsiz mi?
Evet — “Tuzaklar: Sabitleme ve ThreadLocals” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Java Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Java Academy kursu toplamda 4 dersten oluşur.
“Tuzaklar: Sabitleme ve ThreadLocals” dersinde ne öğreneceğim?
Taşıyıcı iş parçacıklarını engellemekten kaçının Java Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Java Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Java Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“Tuzaklar: Sabitleme ve ThreadLocals” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Java Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Java Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Sanal İş Parçacıkları Nedir
- Sanal İş Parçacıkları Oluşturma
- Platform ve Sanal İş Parçacıkları
- Tuzaklar: Sabitleme ve ThreadLocals