Eşzamanlılık, Engelleme Sıraları (Java 7) - 1

"Merhaba, Amigo!"

"Merhaba Kim!"

"Bugün size eşzamanlılıktan bahsedeceğim."

" Eşzamanlılık , birden çok iş parçacığından çalışmak için optimize edilmiş özel sınıflar içeren bir Java sınıf kitaplığıdır. Bu çok ilginç ve kapsamlı bir konudur. Ancak bugün sadece bir giriş yapacağız. Paketin adı java.util. Eşzamanlı paket. Size birkaç ilginç dersten bahsedeceğim."

" Atomik tipler. "

"count++'ın bile iş parçacığı güvenli bir işlem olmadığını zaten biliyorsunuz. Bir değişken 1 artırıldığında, aslında üç işlem gerçekleşir. Sonuç olarak, değişken değiştirildiğinde bir çakışma olabilir."

"Evet, Ellie kısa bir süre önce bana şunları söyledi:"

konu 1 Konu 2 Sonuç
register1 = count;
register1++;
count = register1;
register2 = count;
register2++;
count = register2;
register1 = count;
register2 = count;
register2++;
count = register2;
register1++;
count = register1;

"Kesinlikle. Sonra Java, bu işlemleri tek olarak, yani atomik olarak (bir atom bölünmezdir) gerçekleştirmek için veri türleri ekledi."

"Örneğin, Java'da AtomicInteger, AtomicBoolean, AtomicDouble vb. var."

"Bir «karşı» sınıf oluşturmamız gerektiğini varsayalım:"

Örnek
class Counter
{
 private int c = 0;

 public void increment()
 {
  c++;
 }

 public void decrement()
 {
  c--;
 }

 public int value()
 {
  return c;
 }
}

"Bu sınıftaki nesneleri iş parçacığı için güvenli hale nasıl getirirsiniz?"

"Pekala, tüm yöntemleri senkronize ederdim ve onunla işim biterdi:"

Örnek
class synchronized Counter
{
 private int c = 0;

 public synchronized void increment()
 {
  c++;
 }

 public synchronized void decrement()
 {
  c--;
 }

 public synchronized int value()
 {
  return c;
 }
}

"İyi iş. Ama atomik tipler kullansaydık nasıl görünürdü:"

Örnek
class AtomicCounter
{
 private AtomicInteger c = new AtomicInteger(0);

 public void increment()
 {
  c.incrementAndGet();
 }

 public void decrement()
 {
  c.decrementAndGet();
 }

 public int value()
 {
  return c.get();
 }
}

"Sizin sınıfınız ve benim sınıfım aynı şekilde çalışır, ancak AtomicInteger'a sahip sınıf daha hızlı çalışır."

"Peki, küçük bir fark mı?"

"Evet. Deneyimlerime dayanarak, her zaman synchronized ile başlamanızı öneririm. Yalnızca tüm uygulama kodu yazıldığında ve optimizasyon süreci başladığında, atomik türleri kullanmak için kodu yeniden yazmaya başlamalısınız. Ama her durumda, seni istedim. aktif olarak kullanmasanız bile, kullanıldıkları yerde kodla karşılaşma şansınız her zaman vardır."

"Katılıyorum. Bu mantıklı."

"Bu arada, atomik tiplerin değişmez olmadığını fark ettiniz mi? Standart Integer sınıfının aksine AtomicInteger , dahili durumunu değiştirmek için yöntemler içerir."

"Anladım. Tıpkı String ve StringBuffer gibi ."

"Evet, onun gibi bir şey."

" Güvenli koleksiyonlar. "

"Böyle bir koleksiyona örnek olarak ConcurrentHashMap'i sunabilir miyim. HashMap'i iş parçacığı için güvenli hale nasıl getirirsiniz?"

"Bütün yöntemleri senkronize edilsin mi?"

"Elbette, ama şimdi böyle bir EşitlenmişHashMap'iniz olduğunu ve ona erişen düzinelerce iş parçacığınız olduğunu hayal edin. Ve haritaya saniyede yüz kez yeni bir giriş eklenir ve bu süreçte tüm nesne okuma ve yazma için kilitlenir."

"Pekala, bu standart yaklaşım. Ne yapabilirsin?"

"Java'nın yaratıcıları birkaç harika şey buldu."

"İlk olarak, verileri tek bir blokta bir ConcurrentHashMap'te depolarlar, ancak onu 'demetler' adı verilen parçalara bölerler. Ve birisi bir ConcurrentHashMap'teki verileri değiştirdiğinde, o zaman tüm nesne yerine yalnızca erişilen demeti kilitleriz. Diğerinde kelimeler, birçok iş parçacığı nesneyi aynı anda değiştirebilir."

"İkincisi, aynı anda liste/harita öğeleri üzerinde yineleme yapıp listeyi değiştiremeyeceğinizi hatırlıyor musunuz? Böyle bir kod bir istisna atar:"

Bir döngüdeki bir koleksiyonun öğeleri üzerinde yineleme yapmayın ve aynı anda onu değiştirmeyin
HashMap<String, Integer> map = new HashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"Ancak ConcurrentHashMap'te şunları yapabilirsiniz:"

Bir döngüdeki bir koleksiyonun öğeleri üzerinde yineleme yapmayın ve aynı anda onu değiştirmeyin"
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<String, Integer>();

for (String key: map.keySet())
{
 if (map.get(key) == 0)
  map.remove(key);
}

"Eşzamanlı paketin birçok avantajı var. Sadece bu sınıfları kullanabilmek için çok iyi anlamamız gerekiyor."

"Anlıyorum. Teşekkürler Kim. Bunlar gerçekten ilginç dersler. Umarım bir gün bu derslerde bir virtüöz gibi ustalaşırım."