Bu yazıda, iş parçacığını kontrol etmek için wait() yöntemine ve notify() / notifyAll() yöntemlerine bakacağız . Bu yöntemler java.lang.Object temel sınıfında tanımlanır ve buna göre Java'daki kalıtım mekanizmaları bu yöntemleri kesinlikle tüm sınıflara sağlar. Yani, kendi sınıfınızı ve onun nesnelerini oluşturduğunuzda, bu metotları her zaman çağırabilirsiniz.

wait() ve notify()/notifyAll() yöntemleri nasıl çalışır?

  • bekle() . kısacası, bu yöntem monitörü serbest bırakır ve çağıran iş parçacığını başka bir iş parçacığı notify () / notifyAll() yöntemini çağırana kadar bekleme durumuna alır;
  • bildir() . Daha önce wait() yöntemi çağrılan bir iş parçacığının çalışmasına devam eder;
  • notifyAll() yöntemi, daha önce wait() yöntemi çağrılan tüm dizileri devam ettirir.
Şimdi wait() yöntemine daha yakından bakalım . Object sınıfı , bu yöntem için üç seçenek içerir:
  • public final yerel void wait(long timeoutMillis) atar InterruptedException ; Geçerli iş parçacığının uyanana kadar beklemesine neden olur. Genellikle bildirim alarak veya kesintiye uğrayarak veya belirli bir gerçek süre geçene kadar gerçekleşir.

  • public final void wait(), InterruptedException öğesini atar . İkincisi olarak parametresiz bir metot yazmamız tesadüf değil. Aslında, koduna bakarsanız, yöntemin ilk varyantına atıfta bulunur, sadece 0L argümanına sahiptir.

  • public final wait​(uzun zaman aşımı, int nanos) . Geçerli iş parçacığının, genellikle bildirim alınarak veya kesintiye uğratılarak uyandırılana kadar veya belirli bir gerçek zaman geçene kadar beklemesine neden olur.

wait () yöntemi, çağıran iş parçacığını askıya almayı amaçlar. Bu ne anlama geliyor? Bu metotlar sınıfa aittir. Sınıfa bağlı olarak bir nesne yaratırsınız. Nesneler bazı iş parçacıklarında bulunur. Yani, nesneler bazı iş parçacıklarında oluşturulur. Bu nesnenin çalıştığı iş parçacığında, içinde wait() öğesini çağırırsanız , bu iş parçacığının durmasına yol açacaktır. Nesnenin kendisi bir tür monitör görevi görür. Nedir? Açıktır ki farklı nesneler yaratabilirsiniz ve bunların hepsi wait() işlevini içerecektir.yöntem. Hangi nesnenin belirli bir iş parçacığının durmasına neden olduğu konusunda bir anlayış var. İş parçacığı durur ve parametrede yazıldığı sürece bekler. Ve sonra başlayacak. Bu iş parçacığı kendi kendine başlayamaz. Çalışmaya devam etmek için notify ve notifyAll yöntemleri vardır. notify() veya notifyAll() çağrısı başka bir iş parçacığını oynatmalıdır. wait() ile birden fazla diziyi durdurabilir ve tüm dizileri notifyAll() ile başlatabilirsiniz . Birden fazla iş parçacığı durdurulduysa ve notify() çağrıldıysa, tam olarak hangi iş parçacığının bu yöntemi devam ettireceğini söylemek imkansızdır. wait() yönteminde bekleyen iş parçacığı yoksa , notify() veyanotifyAll() çağrılır. Bir iş parçacığı , yalnızca şu anda o nesne üzerinde bir kilidi varsa, belirli bir nesnede wait() veya notify() yöntemlerini çağırabilir . wait() , notify() ve notifyAll() yalnızca senkronize edilmiş koddan çağrılmalıdır.

Wait() yöntemi örneği

Burada, yöntemin nasıl çalıştığını gösteren en popüler örneklerden birine sahibiz. Diyelim ki bir mağazamız, bir üreticimiz ve bir tüketicimiz var. Üretici, bazı üretim ürünlerini mağazaya aktarır ve ardından tüketici bunları alabilir. Üretici sırasıyla 8 mal üretsin, tüketici hepsini satın almalıdır. Ancak aynı anda depoda 6'dan fazla ürün bulunamaz. Bu sorunu çözmek için wait() ve notify() metotlarını kullanıyoruz . Üç sınıf tanımlayalım: Market , Manufacturer ve Client . Run() yöntemindeki Üretici , Market nesnesine 8 ürün ekler.koymak() yöntemi. Bir döngüdeki run() yöntemindeki istemci, bu ürünleri almak için Market nesnesinin get yöntemini çağırır . Market sınıfının koy ve al yöntemleri senkronize edilir. Market sınıfındaki malların varlığını izlemek için , item değişkeninin değerini kontrol ederiz. Bir ürünü almak için get () yöntemi, yalnızca en az bir ürün varsa tetiklenmelidir. Bu nedenle get yönteminde ürünün eksik olup olmadığını kontrol ederiz. Öğe mevcut değilse, wait() yöntemi çağrılır. Bu yöntem, Market nesnesinin izleyicisini serbest bırakır ve get yöntemini notify() işlevi gerçekleşene kadar engeller.yöntem aynı monitörde çağrılır. put() yöntemine bir öğe eklendiğinde ve notify() çağrıldığında, get() yöntemi monitörü alır. Bundan sonra müşterimiz bir ürün alır. Bunu yapmak için bir mesaj görüntülenir ve öğenin değeri azaltılır. Son olarak, notify() yöntemi çağrısı, put() yöntemine devam etmesi için işaret verir. put() yönteminde benzer mantık çalışır, ancak şu anda pazarda 6'dan fazla ürün yoksa put() yöntemi çalışmalıdır .

class Market {

   private int item = 0;

   public synchronized void get() {
       //here we use wait() method
       while (item < 1) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item--;
       System.out.println("A client has bought 1 item...");
       System.out.println("Items quantity in Market warehouse... " + item);
       notify();
   }

   public synchronized void put() {
       //here we use wait() method when the Warehouse is full
       while (item >= 6) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item ++;
       System.out.println("Manufacturer has added 1 more item...");
       System.out.println("Now there are " + item + " items in Warehouse" );
       notify();
   }
}

class Manufacturer implements Runnable {

   Market market;

   Manufacturer(Market market) {
       this.market = market;
   }


   public void run() {
       for (int i = 0; i < 8; i++) {
           market.put();
       }
   }
}

class Client implements Runnable {

   Market market;
   Client(Market market) {
       this.market = market;
   }
   public void run() {
       for (int i = 0; i < 8; i++) {
           market.get();
       }
   }
}
//wait() method test class
public class WaitTest {
   public static void main(String[] args) {

       Market market = new Market();
       Manufacturer manufacturer = new Manufacturer(market);
       Client client = new Client(market);
       new Thread(manufacturer).start();
       new Thread(client).start();
   }
}
Burada get() yönteminde wait() kullanarak, Üreticinin yeni bir öğe eklemesini bekliyoruz . Ve ekledikten sonra, sanki Warehouse'da bir yer boşaldı ve siz daha fazlasını ekleyebilirsiniz demek için notify() diyoruz . put() yönteminde wait() kullanarak , Warehouse üzerinde yer açılmasını bekliyoruz . Alan boşaldıktan sonra öğeyi ekleriz, notify() ileti dizisini başlatır ve İstemci öğeyi alabilir. İşte programımızın çıktısı:
Üretici 1 ürün daha ekledi... Depoda 1 ürün var Üretici 1 ürün daha ekledi... Depoda 2 ürün var Üretici 1 ürün daha ekledi... Depoda 3 ürün var Üretici ekledi 1 ürün daha ekledi... Depoda 4 ürün var 1 ürün daha ekledi... Depoda 5 ürün var Üretici 1 ürün daha ekledi... Depoda 6 ürün var Bir müşteri satın aldı 1 adet... Market deposundaki ürün miktarı... 5 Bir müşteri 1 ürün satın aldı... Market deposundaki ürün miktarı... 4 Bir müşteri 1 ürün satın aldı... Market deposundaki ürün miktarı... 3 Bir müşteri 1 ürün satın aldı... Market deposundaki ürün miktarı... 2 Bir müşteri 1 ürün satın aldı... Market deposundaki ürün miktarı... 1 Bir müşteri 1 ürün satın aldı... Market deposundaki ürün miktarı ...0 Üretici 1 ürün daha ekledi... Depoda 1 ürün var Üretici 1 ürün daha ekledi... Depoda 2 ürün var Bir müşteri 1 ürün aldı... Market deposundaki ürün miktarı... 1 Müşteri 1 adet ürün satın aldı... Market deposundaki ürün miktarı... 0 Çıkış kodu ile işlem tamamlandı 0