Synckronizasyon Java
Nedir? Synckronizasyon Java?
In Java, senkronizasyon, birden fazla iş parçacığının herhangi bir paylaşılan kaynağa erişimini kontrol etme yeteneğini ifade eder. Paylaşılan kaynağa yalnızca bir iş parçacığının erişmesine izin vermek istediğimizde ideal bir seçenektir.
Bu yürütme yaklaşımına genellikle `asenkron` programlama denir. Bu işlemcilerde ayrıca talimatları eş zamanlı olarak yürütebilen hafif süreçler olan iş parçacıkları da bulunur.
Tipleri Synckronizasyon
İki tür senkronizasyon yöntemi vardır Java:
1) İşlem senkronizasyonu
2) İş parçacığı senkronizasyonu.
Konuyu inceleyelim ve İşlem senkronizasyonu detayda.
İşlem senkronizasyonu: Programlar arasındaki senkronizasyonu yönetir. Örneğin, ` gibi programlarMicrosoft Word` ve `Acrobat Reader` ayrı işlemler olarak çalışır.
İş parçacığı senkronizasyonu: Kritik kaynağın iki veya daha fazla İş Parçacığı tarafından eşzamanlı yürütülmesine İş Parçacığı adı verilir Synckronizasyon. Birbirini dışlayan ve iş parçacığı arası iletişim için daha fazla gruplandırılabilirsiniz.
Kilitlenmek Nedir? Java?
İçeri kilitlemek Java monitör veya kilit olarak bilinen dahili bir varlığın etrafında inşa edilmiştir. Tüm nesnelerin kendileriyle ilişkili bir kilidi vardır. Bu nedenle, bir nesnenin alanlarına tutarlı erişime ihtiyaç duyan iş parçacığının, bunlara erişmeden önce nesnenin kilidini alması gerekir ve iş bittiğinde kilidi serbest bırakır. Bu, aynı anda yalnızca bir iş parçacığının paylaşılan verilere erişmesini sağlar.
Senkronizasyonlu çok iş parçacıklı program
Çok iş parçacıklı bir program `syncronized` anahtar sözcüğü kullanılarak belirtilen aynı kaynağı paylaşan diğer iş parçacıklarının müdahalesinden korunan bir yöntem veya bloktur.
Eşzamanlı yöntemi kullanma
Eşzamanlı olarak bildirilen herhangi bir yönteme eşzamanlanmış Yöntem denir. Ayrıca, herhangi bir paylaşılan kaynak için bir nesneyi kilitlemek için kullanılır. Yani, bir iş parçacığı eşzamanlanmış bir yöntemi çağırdığında. Otomatik olarak o nesnenin kilidini ele geçirir ve görevini tamamladığında serbest bırakır.
Not: synchronized anahtar sözcüğü sınıflar ve değişkenlerle çalışamaz. Anahtar sözcükle yalnızca yöntemler ve bloklar kullanılabilir.
neden kullan Synckronikleştirilmiş Yöntem?
- Herhangi bir paylaşılan kaynak için bir nesneyi kilitlemek için kullanılır.
- Eşzamanlı yöntem çağrıldığında nesne kilidi alır.
- İplik işlevini tamamlayana kadar kilit açılmaz
Sözdizimi:
Acess_modifiers synchronized return_type method_name (Method_Parameters) { }
class MathService { synchronized void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); } }
Kodun Açıklaması:
Bu örneği çalıştırın ve ilk önce "0" iş parçacığının "mathService" nesnesinin kilidini aldığını ve yürütmeyi tamamlayana kadar bu kilidi özel olarak kullandığını gözlemleyin. İş parçacığı '0' ve '1' bu kodda araya eklenmez. Çıktı aşağıda gösterildiği gibidir.
Çıktı:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Eşzamanlı bir blok kullanma
Tüm yöntemi senkronize etmek istemediğinizi varsayalım. Bunun yerine birkaç satır kodu senkronize etmek istiyorsunuz. O zaman, Synchronized blok, seçilenlerin senkronize edilmesine yardımcı oldu Java kodu. SyncEşzamanlı yöntem kilitlerine yöntem üzerinde erişilirken, eşzamanlanmış blok kilitlerine nesne üzerinde erişilir.
class MathService { void getSumOfArray(int[] numbers) { synchronized (this){ int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); } }
Kod Açıklaması:
Bu kodu çalıştırdığınızda, herhangi bir müdahale olmadan çalıştığını göreceksiniz. Eşzamanlı yöntemde, kilit yöntem tarafından uygulanır, ancak eşzamanlanmış blokta, kilit nesne tarafından uygulanır. Çıktının aşağıda gösterildiği gibi olduğundan emin olun.
Çıktı:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Kodun açıklaması:
Bu kodu çalıştırdığınızda, beklediğimiz gibi, herhangi bir müdahale olmadan çalıştığını göreceksiniz. Eşzamanlı yöntemde, kilit yöntem tarafından uygulanır, ancak eşzamanlanmış blok yönteminde, kilit nesne tarafından uygulanır.
Statik senkronizasyonu kullanma
In Java senkronizasyon, birden fazla nesne varsa, iki iş parçacığı kilitleri edinebilir ve her nesne için ayrı bir kilitle senkronize bir blok veya bloğa girebilir. Bunu önlemek için statik senkronizasyon kullanılabilir. SyncStatik yöntemlerden önce hronized anahtar kelimeler kullanılacaktır.
Not: Statik senkronizasyonda kilit erişimi nesne ve metot üzerinde değil, sınıf üzerindedir.
Birden çok nesnenin kilitlenmesi sorununu gösteren kod
class MathService { synchronized void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); MathService mathService1 = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); Thread threadThree = new Thread(() -> mathService1.getSumOfArray(new int[]{10, 11, 12})); Thread threadFour = new Thread(() -> mathService1.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); threadThree.start(); threadFour.start(); } }
Kodun açıklaması:
'MathService'in başka bir örneğini oluşturduğumuzda, iki nesneyle serpiştirilecekleri için iş parçacıklarında girişime neden oluyoruz. '0' ve '2' iş parçacığının iki nesneyle serpiştirildiğini, '1' ve '3' iş parçacığının ise iki nesneyle serpiştirildiğini unutmayın.
Çıktı:
Thread-0 adds 0 to 10 to get -> 10 Thread-2 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-2 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-3 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-3 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63 Thread-3 adds 41 to 22 to get -> 63
Aynı kod, senkronize statik yöntemi kullanıyor
class MathService { synchronized static void getSumOfArray(int[] numbers) { int sum = 0; for (int number : numbers) { System.out.println(Thread.currentThread() .getName() + " adds " + sum + " to " + number + " to get -> " + (sum += number)); try { Thread.sleep(500); } catch (InterruptedException e) { throw new RuntimeException(e); } } } } public class Synchronization { public static void main(String[] args) { MathService mathService = new MathService(); MathService mathService1 = new MathService(); Thread threadOne = new Thread(() -> mathService.getSumOfArray(new int[]{10, 11, 12})); Thread threadTwo = new Thread(() -> mathService.getSumOfArray(new int[]{20, 21, 22})); Thread threadThree = new Thread(() -> mathService1.getSumOfArray(new int[]{10, 11, 12})); Thread threadFour = new Thread(() -> mathService1.getSumOfArray(new int[]{20, 21, 22})); threadOne.start(); threadTwo.start(); threadThree.start(); threadFour.start(); } }
Yukarıdaki kodu çalıştırın ve artık iş parçacığı girişimini ortadan kaldırdığımızı unutmayın. Kodun çıktısı aşağıda gösterilmiştir.
Çıktı:
Thread-0 adds 0 to 10 to get -> 10 Thread-0 adds 10 to 11 to get -> 21 Thread-0 adds 21 to 12 to get -> 33 Thread-3 adds 0 to 20 to get -> 20 Thread-3 adds 20 to 21 to get -> 41 Thread-3 adds 41 to 22 to get -> 63 Thread-2 adds 0 to 10 to get -> 10 Thread-2 adds 10 to 11 to get -> 21 Thread-2 adds 21 to 12 to get -> 33 Thread-1 adds 0 to 20 to get -> 20 Thread-1 adds 20 to 21 to get -> 41 Thread-1 adds 41 to 22 to get -> 63
Senkronizasyonun kullanılmasının avantajları
Eşzamanlı uygulamalarla çalışmanın avantajları şunlardır:
- Senkronizasyonun temel amacı Java iş parçacığının karışmasını önleyerek tutarsız verilerin oluşmasını engellemektir.
- Eşzamanlı anahtar kelime Java Paylaşılan kaynağa karşılıklı olarak özel erişimi garanti altına alan ve veri yarışını engelleyen kilitleme özelliği sunar.
- Ayrıca kod ifadelerinin kod ifadelerinin yeniden sıralanmasını da önler. derleyiciBu, uçucu veya senkronize anahtar sözcükleri kullanmazsak, eşzamanlı bir soruna neden olabilir.
- Synchronized anahtar kelime, ana bellekteki verileri önbellekten okur ve kilidi serbest bıraktığında.
- Ayrıca yazma işlemlerini ana bellekten temizleyerek bellek tutarsızlığı hatalarını ortadan kaldırır.
Dezavantajları SyncHronizasyon Mekanizması
Synchronizasyon Mekanizmaları düşük performansa sahiptir.
Örneğin
- A1, A2, A3, A4 ve A5 olmak üzere beş süreç olduğunu varsayalım.
- Paylaşılan kaynakların aynı anda bir iş parçacığına erişmesini bekliyorlar.
- Tüm işlemler beklemede tutulur, bu nedenle kuyruktaki son işlemin diğer tüm işlemler tamamlanana kadar beklemesi gerekir.
ÖZET
- Synchronizasyon, birden fazla iş parçacığının herhangi bir paylaşılan kaynağa erişimini kontrol etme yeteneğini ifade eder.
- Java iki tür senkronizasyon yöntemi vardır: 1) İşlem senkronizasyonu ve 2) İş parçacığı senkronizasyonu.
- İçeri kilitlemek Java monitör veya kilit olarak bilinen dahili bir varlığın etrafında inşa edilmiştir.
- Çok iş parçacıklı program, `syncronized` anahtar sözcüğü kullanılarak belirtilen aynı kaynağı paylaşan diğer iş parçacıklarından gelen müdahaleden korunan bir yöntem veya bloktur.
- Eşzamanlı olarak tanımlanan herhangi bir yönteme eşzamanlı yöntem denir.
- In JavaEşzamanlı yöntem kilitlerine yöntem üzerinde erişilirken, eşzamanlı blok kilitlerine nesne üzerinde erişilir.
- Statik senkronizasyonda kilit erişimi nesne ve metot üzerinde değil, sınıf üzerindedir.
- Senkronizasyonun temel amacı Java iş parçacığının karışmasını önleyerek tutarsız verilerin oluşmasını engellemektir.
- Bu yöntemin en büyük dezavantajı tüm süreçlerin beklemede tutulması, dolayısıyla kuyruktaki sonuncunun diğer tüm süreçler tamamlanana kadar beklemesi gerektiğidir.