ProgramlamaJava orta/arka uç geliştirici

Java'da iş parçacıklarıyla ilgili ne biliyorsunuz ve iş parçacığı güvenliğini nasıl sağlarsınız?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Java'da iş parçacıkları Thread, Runnable sınıfları ve java.util.concurrent paketinden sınıflarla gerçekleştirilir. İş parçacığı güvenliğinin sağlanması için çeşitli senkronizasyon mekanizmaları kullanılır:

  • Senkronize bloklar/yöntemler (synchronized) birden fazla iş parçacığının ortak verilere yarış olmadan erişmesini sağlar.
  • volatile değişkenin değerinin iş parçacıkları arasında görünürlüğünü garanti eder.
  • java.util.concurrent'ten sınıflar (örneğin, ReentrantLock, Semaphore, AtomicInteger, ConcurrentHashMap) daha esnek senkronizasyon yöntemleri sağlar.

Senkronizasyon örneği:

public class Counter { private int count = 0; public synchronized void increment() { count++; } public int getCount() { return count; } }

Atıl sınıflar kullanarak bir örnek:

import java.util.concurrent.atomic.AtomicInteger; public class AtomicCounter { private AtomicInteger count = new AtomicInteger(0); public void increment() { count.incrementAndGet(); } public int getCount() { return count.get(); } }

Sorgu.

volatile anahtar kelimesi, int türünde bir sayaçta artırım için iş parçacığı güvenliğini garanti eder mi?

Cevap: Hayır. volatile yalnızca değerlerin iş parçacıkları arasında görünürlüğünü sağlar, ancak işlemlerin atomikliğini garanti etmez. Artırım — atomik bir işlem değildir (count++ okuma, artırma ve yazma işlemlerinden oluşur), bu nedenle veri kaybı yaşanabilir. İş parçacığı güvenli bir artırım için senkronizasyon ya da AtomicInteger gibi sınıflar gereklidir.

volatile int count = 0; // count++ iş parçacığı güvenli değildir!

Konuyla ilgili hata örnekleri.


Hikaye

Bir çevrimiçi mağazada bonus hesabı, volatile sayaç aracılığıyla güncelleniyordu. Yük altında binlerce kullanıcı ürün siparişi verirken, bazı bonuslar count++ üzerindeki iş parçacığı yarışı nedeniyle kayboluyordu.


Hikaye

Bir çalışan, çoklu iş parçacıklı uygulamada üretici ve tüketici arasında ortak bir tampon olarak normal bir ArrayList kullandı, sonuç olarak ConcurrentModificationException hataları ortaya çıktı. Çözüm, senkronize blokların kullanılması veya CopyOnWriteArrayList ile değiştirilmesiydi.


Hikaye

Ödeme işlemlerinde bir geliştirici "miktarı kontrol et ve çek" işlemini iki bağımsız yöntem aracılığıyla yapıyordu. Yüksek bir yük altında bu, çift tahsilata neden oluyordu ve atomik işlemler ve kilitler uygulanana kadar bu durum devam etti.