CodeGym /Java Blogu /Rastgele /Java'da çoklu kullanım
John Squirrels
Seviye
San Francisco

Java'da çoklu kullanım

grupta yayınlandı
MERHABA! Her şeyden önce tebrikler: Java'da Multithreading konusuna ulaştınız! Bu ciddi bir başarı - uzun bir yol kat ettiniz. Ancak kendinizi hazırlayın: Bu, kurstaki en zor konulardan biridir. Ve burada karmaşık sınıflar veya çok sayıda yöntem kullandığımızdan değil: aslında yirmiden az kullanacağız. Daha çok, nasıl düşündüğünüzü biraz değiştirmeniz gerekecek. Önceden, programlarınız sıralı olarak yürütülüyordu. Bazı kod satırları diğerlerinden sonra geldi, bazı yöntemler diğerlerinden sonra geldi ve temelde her şey açıktı. Önce bir şey hesapladık, sonra konsolda sonucu gösterdik ve sonra program sona erdi. Çoklu okumayı anlamak için paralellik açısından düşünmek daha iyidir. Oldukça basit bir şeyle başlayalım: ) Ailenizin bir evden diğerine taşındığını hayal edin. Tüm kitaplarınızı toplamak, taşınmanın önemli bir parçası olacaktır. Bir sürü kitap biriktirdin ve onları kutulara koyman gerekiyor. Şu anda müsait olan tek kişi sizsiniz. Annem yemek hazırlıyor, erkek kardeş kıyafetleri topluyor ve kız kardeş dükkana gitti. Tek başına, bir şekilde idare edebilirsin. Er ya da geç, görevi kendiniz tamamlayacaksınız, ancak çok zaman alacaktır. Ancak kız kardeşiniz 20 dakika sonra dükkandan dönecek ve yapacak başka bir şeyi yok. Böylece sana katılabilir. Görev değişmedi: kitapları kutulara koyun. Ama iki kat daha hızlı yapılıyor. Neden? Çünkü işler paralel ilerliyor. İki farklı 'iş parçacığı' (siz ve kız kardeşiniz) aynı görevi aynı anda gerçekleştiriyorsunuz. Ve hiçbir şey değişmezse, o zaman her şeyi kendi başınıza yaptığınız duruma kıyasla çok büyük bir zaman farkı olacaktır. Kardeş işini kısa sürede bitirirse sana yardım edebilir ve işler daha da hızlı ilerler.

Multithreading ile çözülen problemler

Multithreading aslında iki önemli hedefe ulaşmak için icat edildi:
  1. Aynı anda birkaç şey yapın.

    Yukarıdaki örnekte, farklı gruplar (aile üyeleri) paralel olarak birkaç eylem gerçekleştirmiştir: bulaşıkları yıkadılar, mağazaya gittiler ve eşyaları paketlediler.

    Programlama ile daha yakından ilgili bir örnek sunabiliriz. Kullanıcı arayüzü olan bir programınız olduğunu varsayalım. Programda 'Devam Et' butonuna tıkladığınızda bazı hesaplamalar yapılmalı ve kullanıcı aşağıdaki ekranı görmelidir. Bu eylemler sırayla gerçekleştirilirse, kullanıcı 'Devam Et' düğmesini tıkladıktan sonra program askıda kalırdı. Program tüm dahili hesaplamaları yapana ve kullanıcı arayüzünün yenilendiği kısma gelene kadar kullanıcı 'Devam Et' butonu ekranının olduğu ekranı görecektir.

    Pekala, sanırım birkaç dakika bekleyeceğiz!

    Java'da çoklu kullanım: nedir, faydaları ve yaygın tuzakları - 3

    Veya programımızda yeniden çalışabilir veya programcıların dediği gibi onu "paralelleştirebiliriz". Hesaplamalarımızı bir iş parçacığında yapalım ve diğerinde kullanıcı arayüzünü çizelim. Çoğu bilgisayarın bunu yapmak için yeterli kaynağı vardır. Bu rotayı izlersek, program donmayacak ve kullanıcı içeride ne olduğu konusunda endişelenmeden ekranlar arasında sorunsuz hareket edecektir. Biri diğerine karışmaz :)

  2. Hesaplamaları daha hızlı yapın.

    Burada her şey çok daha basit. İşlemcimizin birden fazla çekirdeği varsa ve bugün çoğu işlemcide varsa, o zaman birkaç çekirdek görev listemizi paralel olarak işleyebilir. Açıkçası, 1000 görev gerçekleştirmemiz gerekirse ve her biri bir saniye sürerse, bir çekirdek listeyi 1000 saniyede, iki çekirdek 500 saniyede, üç çekirdek 333 saniyeden biraz fazla bir sürede vb.

Ancak bu derste zaten okuduğunuz gibi, günümüzün sistemleri çok akıllıdır ve tek bir bilgi işlem çekirdeğinde bile görevlerin dönüşümlü olarak gerçekleştirildiği paralellik veya daha doğrusu sözde paralellik elde edebilir. Genellemeleri özele taşıyalım ve Java çoklu okuma kitaplığındaki en önemli sınıfı, java.lang.Thread'i tanıyalım. Açıkça söylemek gerekirse, Java iş parçacıkları, Thread sınıfının örnekleri tarafından temsil edilir . Bu, 10 iş parçacığı oluşturmak ve çalıştırmak için bu sınıfın 10 örneğine ihtiyacınız olduğu anlamına gelir. En basit örneği yazalım:

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("I'm Thread! My name is " + getName());
   }
}
Konu oluşturmak ve çalıştırmak için, bir sınıf oluşturmamız, java.lang'ı devralmasını sağlamamız gerekir . Thread sınıfını seçin ve run() yöntemini geçersiz kılın. Bu son şart çok önemlidir. İş parçacığımızın yürütme mantığını run() yönteminde tanımlarız. Şimdi, bir MyFirstThread örneği oluşturup çalıştırırsak , run() yöntemi, adı olan bir satır görüntüler: getName() yöntemi, iş parçacığının otomatik olarak atanan 'sistem' adını görüntüler. Ama neden geçici olarak konuşuyoruz? Bir tane oluşturalım ve öğrenelim!

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {

           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Konsol çıktısı: Ben Konuyum! Adım Thread-2 Ben Thread! Adım Konu-1 Ben Konuyum! Adım Thread-0 Ben Thread! Adım Thread-3 Ben Thread! Adım Thread-6 Ben Thread! Adım Thread-7 Ben Thread! Adım Thread-4 Ben Thread! Adım Thread-5 Ben Thread! Adım Thread-9 Ben Thread! Benim adım Thread-8 10 adet thread ( Thread'i devralan MyFirstThread nesneleri) oluşturalım ve her nesnede start() yöntemini çağırarak bunları başlatalım . start() yöntemi çağrıldıktan sonra run() yöntemindeki mantık yürütülür. Not: Konu adları sıralı değildir. Sırayla olmamaları garip:, Konu-1 , Konu-2 vb. Olduğu gibi, bu 'sıralı' düşünmenin uymadığı bir zaman örneğidir. Sorun şu ki, yalnızca 10 iş parçacığı oluşturmak ve çalıştırmak için komutlar sağladık. Özel bir işletim sistemi mekanizması olan iş parçacığı zamanlayıcı yürütme sırasına karar verir. Kesin tasarımı ve karar verme stratejisi, şu anda derin bir tartışmaya girmeyeceğimiz konular. Hatırlanması gereken en önemli şey, programcının iş parçacıklarının yürütme sırasını kontrol edemediğidir. Durumun ciddiyetini anlamak için yukarıdaki örnekte bulunan main() yöntemini birkaç kez daha çalıştırmayı deneyin. İkinci çalıştırmada konsol çıktısı: Ben İplik! Adım Thread-0 Ben Thread! Adım Thread-4 Ben Thread! Adım Thread-3 Ben Thread! Adım Thread-2 Ben Thread! Adım Konu-1 Ben Konuyum! Adım Thread-5 Ben Thread! Adım Thread-6 Ben Thread! Adım Thread-8 Ben Thread! Adım Thread-9 Ben Thread! Benim adım Thread-7 Konsolun üçüncü çalıştırma çıktısı: Ben Thread! Adım Thread-0 Ben Thread! Adım Thread-3 Ben Thread! Adım Konu-1 Ben Konuyum! Adım Thread-2 Ben Thread! Adım Thread-6 Ben Thread! Adım Thread-4 Ben Thread! Adım Thread-9 Ben Thread! Adım Thread-5 Ben Thread! Adım Thread-7 Ben Thread! Benim adım Konu-8

Çoklu iş parçacığı tarafından oluşturulan sorunlar

Kitaplarla ilgili örneğimizde, çoklu okumanın çok önemli görevleri çözdüğünü ve programlarımızı daha hızlı hale getirebileceğini gördünüz. Genellikle birçok kez daha hızlı. Ancak multithreading zor bir konu olarak kabul edilir. Nitekim yanlış kullanılırsa çözmek yerine sorun yaratır. "Sorun yaratır" dediğimde, soyut anlamda kastetmiyorum. Çoklu iş parçacığının yaratabileceği iki özel sorun vardır: kilitlenme ve yarış koşulları. Kilitlenme, birden çok iş parçacığının birbiri tarafından tutulan kaynakları beklediği ve hiçbirinin çalışmaya devam edemediği bir durumdur. Sonraki derslerde bunun hakkında daha fazla konuşacağız. Şu örnek şimdilik yeterli olacaktır: Java'da çoklu kullanım: nedir, faydaları ve yaygın tuzakları - 4Thread-1'in bazı Object-1 ile etkileşime girdiğini ve Thread-2'nin Object-2 ile etkileşime girdiğini hayal edin. Ayrıca, program şu şekilde yazılmıştır:
  1. Thread-1, Object-1 ile etkileşimi durdurur ve Thread-2, Object-2 ile etkileşimi durdurur ve Object-1'e geçer geçmez Object-2'ye geçer.
  2. Thread-2, Object-2 ile etkileşimi durdurur ve Thread-1, Object-1 ile etkileşimi durdurur ve Object-2'ye geçer geçmez Object-1'e geçer.
Multithreading konusunda derin bir anlayışa sahip olmasanız bile, hiçbir şeyin olmayacağını kolayca görebilirsiniz. Konular asla yer değiştirmeyecek ve sonsuza kadar birbirini bekleyecek. Hata açık görünüyor, ancak gerçekte öyle değil. Bunu bir programda kolayca yapabilirsiniz. Kilitlenmeye neden olan kod örneklerini sonraki derslerde ele alacağız. Bu arada, Quora'nın kilitlenmenin ne olduğunu açıklayan harika bir gerçek hayat örneği var.dır-dir. 'Hindistan'ın bazı eyaletlerinde, kayıtlı bir çiftçi olmadığınız sürece size tarım arazisi satmazlar. Ancak tarım araziniz yoksa sizi çiftçi olarak kaydetmezler'. Harika! Ne diyebiliriz? :) Şimdi yarış koşullarından bahsedelim. Yarış koşulu, sistemin veya uygulamanın çalışmasının kodun bölümlerinin yürütülme sırasına bağlı olduğu çok iş parçacıklı bir sistem veya uygulamadaki bir tasarım hatasıdır. Hatırlayın, konuları başlattığımız örneğimiz:

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Thread executed: " + getName());
   }
}

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {

           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
Şimdi, programın yemek pişiren bir robotu çalıştırmaktan sorumlu olduğunu hayal edin! Thread-0, yumurtaları buzdolabından çıkarır. Konu-1 ocağı açar. İplik-2 bir tava alır ve ocağa koyar. İplik-3 sobayı yakar. İplik-4 tavaya yağ döker. İplik-5 yumurtaları kırar ve tavaya döker. Thread-6, yumurta kabuklarını çöp kutusuna atar. İplik-7, pişmiş yumurtaları brülörden çıkarır. İplik-8, pişmiş yumurtaları bir tabağa koyar. Thread-9 bulaşıkları yıkar. Programımızın sonuçlarına bakın: İş parçacığı yürütüldü: İş parçacığı-0 Yürütülen iş parçacığı: İş parçacığı-2 İş parçacığı yürütüldü İş parçacığı-1 Yürütülen iş parçacığı: İş parçacığı-4 Yürütülen iş parçacığı: Yürütülen iş parçacığı: İş parçacığı-9 Yürütülen iş parçacığı: İş parçacığı-5 Yürütülen iş parçacığı: İş parçacığı-8 İş parçacığı yürütüldü: Thread-7 Yürütülen thread: Thread-3 Bu bir komedi rutini mi? :) Ve hepsi, programımızın çalışmasının iş parçacıklarının yürütme sırasına bağlı olması nedeniyle. Gerekli sıralamanın en ufak bir ihlali durumunda mutfağımız cehenneme döner ve çılgın bir robot etrafındaki her şeyi yok eder. Bu, çok iş parçacıklı programlamada da yaygın bir sorundur. Bunu bir kereden fazla duyacaksınız. Bu dersi sonlandırırken, çoklu kullanım hakkında bir kitap önermek istiyorum. Java'da çoklu kullanım: nedir, faydaları ve yaygın tuzakları - 6'Uygulamada Java Eşzamanlılığı' 2006'da yazıldı, ancak alaka düzeyini kaybetmedi. Temel bilgilerden en yaygın hatalara ve anti-kalıplara kadar çok iş parçacıklı Java programlamaya adanmıştır. Bir gün multithreading gurusu olmaya karar verirseniz, bu kitap mutlaka okunmalıdır. Sonraki derslerde görüşmek üzere! :)
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION