Java'da çoklu kullanım
Java Virtual Machine, paralel hesaplamayı destekler . Tüm hesaplamalar bir veya daha fazla iş parçacığı bağlamında gerçekleştirilebilir. Birden fazla iş parçacığı için aynı kaynağa veya nesneye erişimi kolayca ayarlayabileceğimiz gibi, tek bir kod bloğunu yürütmek için bir iş parçacığı da ayarlayabiliriz.
Herhangi bir geliştiricinin, kendilerine tahsis edilmiş birden fazla iş parçacığı olan kaynaklar için okuma ve yazma işlemleri sırasında iş parçacıklarıyla çalışmayı senkronize etmesi gerekir.
Kaynağa erişim sırasında güncel verilere sahip olmanız önemlidir, böylece başka bir iş parçacığı onu değiştirebilir ve en güncel bilgileri alırsınız. Bir banka hesabı örneğini alacak olsak bile para gelene kadar onu kullanamazsınız, bu nedenle her zaman güncel verilere sahip olmak önemlidir. Java, dizileri senkronize etmek ve yönetmek için özel sınıflara sahiptir.
İplik nesneleri
Her şey ana (ana) iş parçacığı ile başlar, yani en azından programınızın halihazırda çalışan bir iş parçacığı vardır. Ana iş parçacığı, Callable veya Runnable kullanarak başka iş parçacıkları oluşturabilir . Oluşturma yalnızca dönüş sonucunda farklılık gösterir, Runnable bir sonuç döndürmez ve kontrol edilen bir istisna atamaz. Bu nedenle, dosyalarla verimli çalışma oluşturmak için iyi bir fırsat elde edersiniz, ancak bu çok tehlikelidir ve dikkatli olmanız gerekir.
İş parçacığı yürütmeyi ayrı bir CPU çekirdeğinde planlamak da mümkündür. Sistem, diziler arasında kolayca hareket edebilir ve belirli bir diziyi doğru ayarlarla çalıştırabilir: yani, verileri okuyan dizi önce yürütülür, veriye sahip olur olmaz, ardından doğrulamadan sorumlu olan diziye iletiriz. Bundan sonra, bazı iş mantığını yürütmek için onu iş parçacığına iletiyoruz ve yeni bir iş parçacığı onları geri yazıyor. Böyle bir durumda, 4 iş parçacığı sırayla veri işliyor ve her şey bir iş parçacığından daha hızlı çalışacaktır. Bu tür akışların her biri yerel bir işletim sistemi akışına dönüştürülür, ancak nasıl dönüştürüleceği JVM uygulamasına bağlıdır.
Thread sınıfı, thread oluşturmak ve thread ile çalışmak için kullanılır. Java.util.concurrent'dan alınan sınıflar ve koleksiyonlar gibi soyut kontrol mekanizmalarının yanı sıra standart kontrol mekanizmalarına sahiptir .
Java'da Konu Senkronizasyonu
İletişim, nesnelere erişimi paylaşarak sağlanır. Bu çok etkilidir, ancak aynı zamanda çalışırken hata yapmak çok kolaydır. Hatalar iki durumda ortaya çıkar: iş parçacığı karışması - iş parçacığınıza başka bir iş parçacığı müdahale ettiğinde ve bellek tutarlılığı hataları - bellek tutarlılığı. Bu hataları çözmek ve önlemek için farklı senkronizasyon yöntemlerimiz var.
Java'da iş parçacığı senkronizasyonu monitörler tarafından gerçekleştirilir; bu, bir seferde yalnızca bir iş parçacığının aynı monitör tarafından korunan bir kod bloğunu yürütmesine izin veren üst düzey bir mekanizmadır. Monitörlerin davranışı kilitler açısından ele alınır; bir monitör - bir kilit.
Senkronizasyon, dikkat etmeniz gereken birkaç önemli noktaya sahiptir. İlk nokta karşılıklı dışlamadır - yalnızca bir iş parçacığı monitöre sahip olabilir, dolayısıyla monitördeki senkronizasyon, bir iş parçacığının monitör tarafından korunan senkronize bir bloğa girdiğinde, monitör tarafından korunan bloğa başka hiçbir iş parçacığının giremeyeceği anlamına gelir. ilk iş parçacığı senkronize edilmiş bloktan çıkar. Yani, birden fazla iş parçacığı aynı senkronize bloğa aynı anda erişemez.
Ancak senkronizasyon sadece karşılıklı dışlama değildir. Senkronizasyon, senkronize edilmiş bir bloktan önce veya içinde belleğe yazılan verilerin aynı monitörde senkronize edilmiş diğer iş parçacıkları tarafından görünür olmasını sağlar. Bloktan çıktıktan sonra monitörü serbest bırakıyoruz ve başka bir iş parçacığı onu alıp bu kod bloğunu çalıştırmaya başlayabilir.
Yeni bir iş parçacığı monitörü yakaladığında, o kod bloğuna erişim ve yürütme yeteneği kazanırız ve bu noktada değişkenler ana bellekten yüklenir. Ardından, monitörün önceki sürümü tarafından görünür hale getirilen tüm girişleri görebiliriz.Bir alan üzerindeki okuma-yazma işlemi, alan ya geçici olarak bildirilmişse ya da herhangi bir okuma-yazmadan önce alınan benzersiz bir kilitle korunuyorsa, atomik bir işlemdir . Ancak yine de bir hatayla karşılaşırsanız, yeniden sıralama (sırayı değiştirme, yeniden sıralama) ile ilgili bir hata alırsınız. Bir iş parçacığının diğer iş parçacıkları tarafından üretilen etkileri gözlemleyebildiği, yanlış senkronize edilmiş çok iş parçacıklı programlarda kendini gösterir.
İş parçacıklarının karşılıklı olarak dışlanmasının ve eşitlenmesinin etkisi, yani bunların doğru çalışması, yalnızca senkronize bir bloğa veya örtük olarak bir kilit elde eden bir yönteme girilerek veya açıkça bir kilit elde edilerek elde edilir. Aşağıda bunun hakkında konuşacağız. Her iki çalışma şekli de hafızanızı etkiler ve uçucu değişkenlerle çalışmayı unutmamak önemlidir .
Java'daki geçici alanlar
Bir değişken volatile olarak işaretlenmişse , global olarak kullanılabilir. Bu, bir iş parçacığının geçici bir değişkene erişmesi durumunda , değerini önbellekten kullanmadan önce alacağı anlamına gelir.
Bir yazma, bir monitör sürümü gibi çalışır ve bir okuma, bir monitör yakalama gibi çalışır. Erişim, "daha önce gerçekleştirilen" türünde bir ilişki içinde gerçekleştirilir. Eğer çözerseniz, geçici bir değişkene eriştiğinde A iş parçacığı tarafından görülebilecek tek şey iş parçacığı B değişkenidir. Yani, diğer iş parçacıklarından yaptığınız değişiklikleri kaybetmeyeceğiniz garanti edilir.
Uçucu değişkenler atomiktir, yani böyle bir değişkeni okurken, bir kilit elde ederken kullanılan etkinin aynısı kullanılır - bellekteki veriler geçersiz veya yanlış olarak bildirilir ve uçucu değişkenin değeri yeniden bellekten okunur . Yazarken, bellek üzerindeki etkinin yanı sıra bir kilidi serbest bırakırken kullanılır - belleğe geçici bir alan yazılır.
Java Eşzamanlı
Süper verimli ve çok iş parçacıklı bir uygulama yapmak istiyorsanız, java.util.concurrent paketinde bulunan JavaConcurrent kitaplığından sınıfları kullanmalısınız .
Kitaplık çok hacimli ve farklı işlevlere sahip, bu yüzden içinde ne olduğuna bir göz atalım ve onu bazı modüllere ayıralım:
Eşzamanlı Koleksiyonlar, çok iş parçacıklı bir ortamda çalışmak için bir dizi koleksiyondur. Koleksiyonun tamamına erişimi engelleyen temel sarmalayıcı Collections.synchronizedList yerine, veri segmentlerinde kilitler kullanılır veya verileri paralel olarak okumak için beklemesiz algoritmalar kullanılır.
Kuyruklar - çok iş parçacıklı bir ortamda çalışmak için engellenmeyen ve engellenen kuyruklar. Engellenmeyen kuyruklar, iş parçacıklarını engellemeden hıza ve işleme odaklanır. Engelleme kuyrukları, Üretici veya Tüketici iş parçacıklarını "yavaşlatmanız" gerektiğinde çalışmak için uygundur. Örneğin bazı şartların sağlanmadığı, kuyruğun boş veya dolu olduğu veya serbest Tüketici'nin olmadığı bir durumda .
Eşitleyiciler , iş parçacıklarını eşitlemek için yardımcı programlardır. "Paralel" bilgi işlemde güçlü bir silahtırlar.
Yürütücüler , iş parçacığı havuzlarının daha rahat ve kolay oluşturulması için bir çerçevedir, sonuçların elde edilmesiyle eşzamansız görevlerin zamanlamasını ayarlamak kolaydır.
Kilitler , temel eşitlenmiş , bekle , bildir , notifyAll ile karşılaştırıldığında birçok esnek iş parçacığı eşitleme mekanizmasıdır .
Atom bilimi, ilkel öğeler ve referanslar üzerinde atomik işlemleri destekleyebilen sınıflardır.