CodeGym /Java Blogu /Rastgele /Multithreading: Thread sınıfının yöntemleri ne yapar?
John Squirrels
Seviye
San Francisco

Multithreading: Thread sınıfının yöntemleri ne yapar?

grupta yayınlandı
MERHABA! Bugün multithreading hakkında konuşmaya devam edeceğiz. Şimdi Thread sınıfını ve birkaç yönteminin ne işe yaradığını inceleyelim. Daha önce sınıf yöntemlerini incelerken, genellikle şunu yazardık: <yöntem adı> -> <yöntem ne yapar>. Multithreading: Thread sınıfının metotları ne işe yarar - 1' nin yöntemleriyle bu iş olmaz Thread:) Birkaç örnek vermeden anlayamayacağınız daha karmaşık bir mantıkları var.

Thread.start() yöntemi

Kendimizi tekrar ederek başlayalım. ThreadMuhtemelen hatırladığınız gibi, sınıfınızın sınıfı miras almasını sağlayarak ve yöntemi geçersiz kılarak bir iş parçacığı oluşturabilirsiniz run(). Ama tabii ki kendi kendine başlamayacak. Bunu yapmak için nesnemizin start()yöntemini çağırıyoruz. Multithreading: Thread sınıfının metotları ne işe yarar - 2Bir önceki dersteki örneği hatırlayalım:

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();
       }
   }
}
Not:start() Bir iş parçacığı başlatmak için, yöntem yerineözel yöntemi çağırmalısınızrun()! Bu, özellikle multithreading çalışmaya ilk başladığınızda, yapılması kolay bir hatadır. Örneğimizde, yöntemirun()yerine 10 kezstart(), şunu elde edersiniz:

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {
           MyFirstThread thread = new MyFirstThread();
           thread.run();
       }
   }
}
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ığı-1 Yürütülen iş parçacığı: İş parçacığı-2 Yürütülen iş parçacığı: İş parçacığı-3 Yürütülen iş parçacığı: İş parçacığı-4 Yürütülen iş parçacığı: İş parçacığı-5 Yürütülen iş parçacığı: İş parçacığı-6 Yürütülen iş parçacığı: İş parçacığı-7 Yürütülen iş parçacığı: İş parçacığı-8 Yürütülen iş parçacığı: İş parçacığı-9 Çıktı sırasına bakın: Her şey mükemmel bir sırayla oluyor. Tuhaf, değil mi? Buna alışkın değiliz, çünkü iş parçacıklarının başlatılma ve yürütülme sırasının işletim sistemimizin içindeki üstün bir akıl tarafından belirlendiğini zaten biliyoruz: iş parçacığı planlayıcı. Belki de sadece şanslıydık? Tabii bu şans meselesi değil. Programı birkaç kez daha çalıştırarak bunu doğrulayabilirsiniz. Sorun şu ki, çağrırun()yöntemin doğrudan çoklu okuma ile ilgisi yoktur. Bu durumda program, yöntemi yürüten aynı iş parçacığı olan ana iş parçacığında yürütülecektir main(). Konsolda art arda 10 satır yazdırır ve bu kadar. 10 konu başlatılmamış. Bu nedenle, gelecekte bunu hatırlayın ve kendinizi sürekli kontrol edin. run()Yöntemin çağrılmasını istiyorsanız , arayın start(). Daha ileri gidelim.

Thread.sleep() yöntemi

Geçerli iş parçacığının yürütülmesini bir süre askıya almak için yöntemi kullanırız sleep(). Multithreading: Thread sınıfının metotları ne işe yarar - 3Yöntem sleep(), iş parçacığını uyku moduna geçirmek için gereken süreyi belirten bir argüman olarak birkaç milisaniye alır.

public class Main {

   public static void main(String[] args) throws InterruptedException {

       long start = System.currentTimeMillis();

       Thread.sleep(3000);

       System.out.println(" - How long did I sleep? \n - " + ((System.currentTimeMillis()-start)) / 1000 + " seconds");

   }
}
Konsol çıktısı: - Ne kadar uyudum? - 3 saniye Not: yöntem sleep()statiktir: geçerli iş parçacığını uyutur. Yani, şu anda idam edilen. İşte başka bir önemli nokta: Uyuyan bir iş parçacığı kesilebilir. Bu durumda, program bir InterruptedException. Aşağıda bir örnek ele alacağız. Bu arada, iş parçacığı uyandıktan sonra ne olur? Kaldığı yerden devam edecek mi? Hayır. Bir iş parçacığı uyandıktan sonra, yani argüman olarak geçen süre geçtikten sonra, çalıştırılabilirThread.sleep() hale geçer.durum. Ancak bu, iş parçacığı zamanlayıcının onu çalıştıracağı anlamına gelmez. Uyumayan başka bir ipliği tercih edebilir ve yeni uyanan ipliğimizin biraz sonra işine devam etmesine izin verebilir. Şunu unutmayın: uyanmak, çalışmaya hemen devam etmek anlamına gelmez!

Thread.join() yöntemi

Multithreading: Thread sınıfının metotları ne işe yarar - 4Yöntem join(), başka bir iş parçacığı bitene kadar geçerli iş parçacığının yürütülmesini askıya alır. 2 iş parçacığımız varsa t1ve t2, ve yazarız

t1.join()
işini bitirene t2kadar başlamaz . t1Yöntem join(), iş parçacıklarının yürütme sırasını garanti etmek için kullanılabilir. join()Aşağıdaki örnekte yöntemin nasıl çalıştığını inceleyelim :

public class ThreadExample extends Thread {

   @Override
   public void run() {

       System.out.println("Thread started: " + getName());

       try {
           Thread.sleep(5000);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println("Thread " + getName() + " is finished.");
   }
}


public class Main {

   public static void main(String[] args) throws InterruptedException {

       ThreadExample t1 = new ThreadExample();
       ThreadExample t2 = new ThreadExample();

       t1.start();


 /* The second thread (t2) will start running only after the first thread (t1)
       is finished (or an exception is thrown) */
       try {
           t1.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       t2.start();

       // The main thread will continue running only after t1 and t2 have finished
       try {
           t1.join();
           t2.join();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }

       System.out.println("All threads have finished. The program is finished.");

   }
}
Basit bir sınıf oluşturduk ThreadExample. Görevi, iş parçacığının başladığına dair bir mesaj görüntülemek, 5 saniye uykuya dalmak ve sonunda işin tamamlandığını bildirmektir. Kekin parçası. Ana mantık sınıftadır Main. Yorumlara bakın: Yöntemi, join()dizilerin yürütme sırasını başarılı bir şekilde yönetmek için kullanıyoruz. Bu konuya nasıl başladığımızı hatırlarsanız, yürütme sırası iş parçacığı zamanlayıcısı tarafından gerçekleştirilir. Konuları kendi takdirine bağlı olarak çalıştırır: her seferinde farklı bir şekilde. Burada, t1iş parçacığının önce başlatılacağını ve önce yürütüleceğini, ardındant2iş parçacığı ve ancak bundan sonra programın ana iş parçacığı devam edecek. Hareketli. Gerçek programlarda, genellikle bir iş parçacığının yürütülmesini kesmeniz gereken durumlar bulacaksınız. Örneğin, iş parçacığımız çalışıyor, ancak belirli bir olay veya koşulu bekliyor. Bu meydana gelirse, iş parçacığı durur. Bir çeşit yöntem olsaydı, muhtemelen mantıklı olurdu stop(). Ama o kadar basit değil. Bir zamanlar Java'nın aslında bir Thread.stop()yöntemi vardı ve bir iş parçacığının kesilmesine izin veriyordu. Ancak daha sonra Java kitaplığından kaldırıldı. Bunu Oracle belgelerinde bulabilir ve kullanımdan kaldırılmış olarak işaretlendiğini görebilirsiniz.. Neden? Çünkü başka bir şey yapmadan sadece ipliği durdurdu. Örneğin, iş parçacığı verilerle çalışıyor ve bir şeyi değiştiriyor olabilir. Sonra, işinin ortasında, stop()yöntem tarafından aniden ve belirsiz bir şekilde kesildi. Düzgün bir kapatma olmadan, kaynakların serbest bırakılması olmadan, hatta hata işleme olmadan - bunların hiçbiri yoktu. Biraz abartmak gerekirse, stop()yöntem basitçe yoluna çıkan her şeyi yok etti. Bilgisayarı kapatmak için güç kablosunu prizden çekmek gibiydi. Evet, istediğiniz sonucu elde edebilirsiniz. Ama herkes biliyor ki birkaç hafta sonra bilgisayar ona bu şekilde davrandığınız için size teşekkür etmeyecek. Bu nedenle Java'da iş parçacıklarını kesme mantığı değişti ve artık özel bir interrupt()yöntem kullanıyor.

Thread.interrupt() yöntemi

interrupt()Yöntem bir iş parçacığında çağrılırsa ne olur ? 2 olasılık var:
  1. joinNesne, örneğin or yöntemleri nedeniyle bekleme durumundaysa sleep, bekleme kesilir ve program bir InterruptedException.
  2. İş parçacığı çalışır durumdaysa, interruptednesne üzerinde boole bayrağı ayarlanır.
Ancak bu bayrağın değerini nesne üzerinde kontrol etmeli ve işi kendi başımıza doğru bir şekilde tamamlamalıyız! Bu yüzden Threadsınıfın yöntemi vardır boolean isInterrupted(). Temel kurstaki bir derste olan saat örneğine geri dönelim. Kolaylık sağlamak için biraz basitleştirdik:

public class Clock extends Thread {

   public static void main(String[] args) throws InterruptedException {
       Clock clock = new Clock();
       clock.start();

       Thread.sleep(10000);
       clock.interrupt();
   }

   public void run() {
       Thread current = Thread.currentThread();

       while (!current.isInterrupted())
       {
           try {
               Thread.sleep(1000);
           } catch (InterruptedException e) {
               System.out.println("The thread was interrupted");
               break;
           }
           System.out.println("Tick");
       }
   }
}
Bu durumda saat çalışmaya başlar ve her saniye işlemeye başlar. 10. saniyede saatin akışını kesiyoruz. Bildiğiniz gibi, kesmeye çalıştığımız iş parçacığı bekleme durumlarından birindeyse, sonuç bir InterruptedException. Bu kontrol edilmiş bir istisnadır, bu yüzden kolayca yakalayabilir ve programı bitirmek için mantığımızı çalıştırabiliriz. Ve biz de öyle yaptık. İşte sonucumuz: Tik Tick Tick Tick Tick Tick Tick Tick Tick Tik Tik Tick Tick İş parçacığı kesintiye uğradı Bu, Threadsınıfın en önemli yöntemlerine girişimizi sonlandırıyor. İyi şanlar!
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION