CodeGym /Java Blogu /Rastgele /İş parçacığı senkronizasyonu. senkronize operatör
John Squirrels
Seviye
San Francisco

İş parçacığı senkronizasyonu. senkronize operatör

grupta yayınlandı
MERHABA! Bugün çok iş parçacıklı programlamanın özelliklerini ele almaya ve iş parçacığı senkronizasyonu hakkında konuşmaya devam edeceğiz. İş parçacığı senkronizasyonu.  Senkronize operatör - 1

Java'da senkronizasyon nedir?

Programlama alanının dışında, iki cihazın veya programın birlikte çalışmasına izin veren bir düzenleme anlamına gelir. Örneğin, bir akıllı telefon ve bilgisayar, bir Google hesabıyla senkronize edilebilir ve bir web sitesi hesabı, sosyal ağ hesaplarıyla senkronize edilebilir; birbirine göre. Önceki derslerde, konularımız birbirinden ayrı yaşadı ve çalıştı. Biri bir hesaplama yaptı, ikincisi uyudu ve üçüncüsü konsolda bir şey gösterdi, ancak etkileşime girmediler. Gerçek programlarda bu tür durumlar nadirdir. Birden çok iş parçacığı, aynı veri kümesiyle aktif olarak çalışabilir ve bunları değiştirebilir. Bu sorun yaratır. Aynı yere, örneğin bir metin dosyasına veya konsola metin yazan birden fazla iş parçacığını hayal edin. Bu durumda, dosya veya konsol paylaşılan bir kaynak haline gelir. Diziler birbirlerinin varlığından habersizdir, bu nedenle iş parçacığı zamanlayıcısı tarafından kendilerine ayrılan zamanda yapabildikleri her şeyi yazarlar. Yakın tarihli bir derste, bunun nereye vardığına dair bir örnek gördük. Şimdi hatırlayalım: İş parçacığı senkronizasyonu.  Senkronize operatör - 2Bunun nedeni, iş parçacıklarının eylemlerini birbirleriyle koordine etmeden paylaşılan bir kaynakla (konsol) çalışması gerçeğinde yatmaktadır. İş parçacığı zamanlayıcı, İş Parçacığı-1'e zaman ayırırsa, anında her şeyi konsola yazar. Diğer konuların yazmayı başarmış veya başaramamış olması önemli değil. Sonuç, gördüğünüz gibi iç karartıcı. Bu nedenle çok iş parçacıklı programlamaya özel bir kavram olan mutex (karşılıklı dışlama) getirdiler . Bir muteksin amacıbelirli bir zamanda yalnızca bir iş parçacığının bir nesneye erişebilmesi için bir mekanizma sağlamaktır. Eğer Thread-1 nesne A'nın muteksini alırsa, diğer evreler nesneye erişemez ve nesneyi değiştiremez. Diğer iş parçacıkları, nesne A'nın muteksi serbest bırakılana kadar beklemelidir. İşte hayattan bir örnek: Siz ve diğer 10 yabancının bir egzersize katıldığınızı hayal edin. Sırayla, fikirlerinizi ifade etmeniz ve bir şeyi tartışmanız gerekir. Ama birbirinizi ilk kez gördüğünüz için, sürekli birbirinizin sözünü kesmemek ve öfkeye kapılmamak için bir 'konuşan top' kullanırsınız: sadece topa sahip olan kişi konuşabilir. Bu şekilde iyi ve verimli bir tartışmaya sahip olursunuz. Esasen, top bir mutekstir. Bir nesnenin muteksi bir iş parçacığının elindeyse, diğer iş parçacıkları nesneyle çalışamaz.Objectsınıf, bu da Java'daki her nesnenin bir tane olduğu anlamına gelir.

Senkronize operatör nasıl çalışır?

Yeni bir anahtar kelimeyi tanıyalım: senkronize edilmiş . Belirli bir kod bloğunu işaretlemek için kullanılır. Bir kod bloğu, anahtar kelime ile işaretlenmişse synchronized, o blok aynı anda yalnızca bir iş parçacığı tarafından yürütülebilir. Senkronizasyon farklı şekillerde uygulanabilir. Örneğin, eşitlenecek tüm bir yöntemi bildirerek:

public synchronized void doSomething() {

   // ...Method logic
}
Veya senkronizasyonun bazı nesneler kullanılarak gerçekleştirildiği bir kod bloğu yazın:

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...Some logic available simultaneously to all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
Anlamı basit. Bir iş parçacığı, anahtar sözcükle işaretlenmiş kod bloğunun içine girerse synchronized, anında nesnenin muteksini yakalar ve aynı bloğa veya yönteme girmeye çalışan diğer tüm iş parçacıkları, önceki iş parçacığı işini tamamlayıp monitörü serbest bırakana kadar beklemeye zorlanır. İş parçacığı senkronizasyonu.  Senkronize operatör - 3Bu arada! Kurs sırasında zaten örneklerini gördünüz synchronized, ancak farklı görünüyorlardı:

public void swap()
{
   synchronized (this)
   {
       // ...Method logic
   }
}
Konu sizin için yeni. Ve tabii ki sözdizimi ile ilgili bir karışıklık olacaktır. Bu nedenle, daha sonra farklı yazma yöntemleri nedeniyle kafanızın karışmasını önlemek için hemen ezberleyin. Bunu yazmanın bu iki yolu aynı anlama gelir:

public void swap() {

   synchronized (this)
   {
       // ...Method logic
   }
}


public synchronized void swap() {

   }
}
İlk durumda, yöntemi girer girmez senkronize bir kod bloğu yaratırsınız. thisNesne, yani geçerli nesne tarafından senkronize edilir . synchronizedVe ikinci örnekte, anahtar kelimeyi yöntemin tamamına uygularsınız . Bu, senkronizasyon için kullanılan nesneyi açıkça belirtmeyi gereksiz kılar. Yöntemin tamamı anahtar sözcükle işaretlendiğinden, yöntem sınıfın tüm örnekleri için otomatik olarak eşitlenir. Hangi yolun daha iyi olduğu hakkında bir tartışmaya girmeyeceğiz. Şimdilik, hangi yolu en çok sevdiğinizi seçin :) Asıl önemli olan şunu unutmamak: Bir yöntemi, yalnızca tüm mantığı aynı anda bir iş parçacığı tarafından yürütüldüğünde senkronize edilmiş olarak ilan edebilirsiniz. Örneğin, aşağıdaki yöntemi senkronize etmek bir hata olur doSomething():

public class Main {

   private Object obj = new Object();

   public void doSomething() {

       // ...Some logic available simultaneously to all threads

       synchronized (obj) {

           // Logic available to just one thread at a time
       }
   }
}
Gördüğünüz gibi, yöntemin bir kısmı senkronizasyon gerektirmeyen mantık içeriyor. Bu kod aynı anda birden fazla iş parçacığı tarafından çalıştırılabilir ve tüm kritik yerler ayrı bir blokta ayrılır synchronized. Ve bir şey daha. Ad değiştirme dersinden örneğimizi yakından inceleyelim:

public void swap()
{
   synchronized (this)
   {
       // ...Method logic
   }
}
Not: senkronizasyon, kullanılarak gerçekleştirilirthis. Yani, belirli birMyClassnesneyi kullanmak. Diyelim ki 2 iş parçacığımız (Thread-1veThread-2) ve yalnızca birMyClass myClassnesnemiz var. Bu durumdaThread-1çağırılırsamyClass.swap()nesnenin muteksi meşgul olur vemyClass.swap()metotThread-2muteksin serbest bırakılmasını beklerken askıda kalır. MyClass2 iş parçacığına ve 2 nesneye (myClass1vesahip olacaksakmyClass2, iş parçacığımız senkronize yöntemleri farklı nesneler üzerinde aynı anda kolayca çalıştırabilir. İlk iş parçacığı bunu yürütür:

myClass1.swap();
İkincisi bunu yürütür:

myClass2.swap();
Bu durumda, senkronizasyon belirli bir nesne kullanılarak gerçekleştirildiğinden, yöntem synchronizediçindeki anahtar kelime swap()programın çalışmasını etkilemez. Ve ikinci durumda, 2 nesnemiz var. Böylece threadler birbirleri için sorun yaratmazlar. Sonuçta, iki nesnenin 2 farklı muteksi vardır ve birinin alınması diğerinin alınmasından bağımsızdır .

Statik yöntemlerde senkronizasyonun özel özellikleri

Peki ya statik bir yöntemi senkronize etmeniz gerekirse ?

class MyClass {
   private static String name1 = "Ally";
   private static String name2 = "Lena";

   public static synchronized void swap() {
       String s = name1;
       name1 = name2;
       name2 = s;
   }

}
Muteksin burada nasıl bir rol oynayacağı belli değil. Sonuçta, her nesnenin bir muteksi olduğunu zaten belirledik. Ancak sorun şu ki, yöntemi çağırmak için nesnelere ihtiyacımız yok MyClass.swap(): yöntem statik! Sırada ne var? :/ Aslında burada bir sorun yok. Java'nın yaratıcıları her şeyin icabına baktı :) Kritik eşzamanlı mantık içeren bir yöntem statik ise, o zaman sınıf düzeyinde senkronizasyon yapılır. Daha fazla netlik için yukarıdaki kodu aşağıdaki gibi yeniden yazabiliriz:

class MyClass {
   private static String name1 = "Ally";
   private static String name2 = "Lena";

   public static void swap() {

       synchronized (MyClass.class) {
           String s = name1;
           name1 = name2;
           name2 = s;
       }
   }

}
Prensip olarak, bunu kendiniz düşünebilirdiniz: Hiçbir nesne olmadığı için, senkronizasyon mekanizması bir şekilde sınıfın kendisinde pişirilmelidir. İşte böyle: senkronize etmek için sınıfları kullanabiliriz.
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION