CodeGym /وبلاگ جاوا /Random-FA /متد Wait() در جاوا
John Squirrels
مرحله
San Francisco

متد Wait() در جاوا

در گروه منتشر شد
در این مقاله، متد () water برای کنترل thread و متدهای notify() / notifyAll() را بررسی خواهیم کرد . این متدها در کلاس پایه java.lang.Object تعریف شده‌اند و بر این اساس، مکانیسم‌های ارثی که در جاوا هستند، این متدها را به طور مطلق برای همه کلاس‌ها ارائه می‌کنند. یعنی وقتی کلاس خود و اشیای آن را ایجاد می کنید، همیشه می توانید این متدها را فراخوانی کنید.

روش های wait() و notify()/notifyAll() چگونه کار می کنند؟

  • صبر کن() . به طور خلاصه، این روش مانیتور را آزاد می کند و رشته فراخوان را در حالت انتظار قرار می دهد تا زمانی که رشته دیگری متد notify() / notifyAll() را فراخوانی کند .
  • اعلام کردن() . کار رشته‌ای را ادامه می‌دهد که متد wait() قبلاً فراخوانی شده بود.
  • متد notifyAll() تمام رشته‌هایی را که قبلاً متد ()watch آن‌ها فراخوانی شده بود، از سر می‌گیرد.
حالا بیایید نگاهی دقیق‌تر به متد () water کنیم . کلاس Object شامل سه گزینه برای این متد است:
  • انتظار باطل نهایی بومی عمومی (تایم اوت طولانیMillis) InterruptedException را پرتاب می کند . باعث می شود تا رشته فعلی منتظر بماند تا بیدار شود. معمولاً با اطلاع یا قطع شدن، یا تا زمانی که مقدار مشخصی از زمان واقعی سپری شود، اتفاق می افتد.

  • عمومی void wait() InterruptedException را می اندازد . تصادفی نیست که روشی بدون پارامتر به عنوان روش دوم نوشتیم. در واقع، اگر به کد آن نگاه کنید، به اولین نوع روش اشاره دارد، فقط آرگومان 0L را دارد.

  • انتظار نهایی عمومی (تایم اوت طولانی، نانوهای داخلی) . باعث می شود تا رشته فعلی منتظر بماند تا بیدار شود، معمولاً با اطلاع رسانی یا قطع شدن، یا تا زمانی که مقدار مشخصی از زمان واقعی سپری شود.

متد wait () برای تعلیق رشته فراخوان در نظر گرفته شده است. چه مفهومی داره؟ این متدها متعلق به کلاس هستند. بر اساس کلاس، یک شی ایجاد می کنید. اشیاء در برخی رشته ها وجود دارند. یعنی اشیا در برخی رشته ها ایجاد می شوند. در رشته ای که این شی در آن کار می کند، اگر wait() را در آن فراخوانی کنید، منجر به توقف این موضوع می شود. جسم خود به عنوان نوعی مانیتور عمل می کند. چیست؟ واضح است که می توانید آبجکت های مختلفی ایجاد کنید و همه آنها حاوی متد () water هستند . این درک وجود دارد که کدام شی باعث توقف یک رشته خاص شده است. موضوع متوقف می شود و تا زمانی که در پارامتر نوشته شده است منتظر می ماند. و سپس شروع خواهد شد. این تاپیک نمی تواند خودش شروع شود. برای از سرگیری کار، روش‌های notify و notifyAll وجود دارد. فراخوانی برای notify() یا notifyAll() باید رشته دیگری را پخش کند. با wait() می توانید چندین رشته را متوقف کنید و همه رشته ها را با notifyAll() شروع کنید . اگر چندین thread متوقف شود و notify() فراخوانی شود، نمی‌توان گفت دقیقاً کدام رشته این روش را از سر می‌گیرد. اگر در متد wait() رشته های انتظاری وجود نداشته باشد ، با فراخوانی notify() یا notifyAll() هیچ اتفاقی نمی افتد. یک رشته می تواند متدهای ()waite یا notify() را روی یک شی خاص فراخوانی کند ، تنها در صورتی که در حال حاضر روی آن شی قفل داشته باشد. wait() ، notify() و notifyAll() فقط باید از کد همگام سازی شده فراخوانی شوند.

مثال روش Wait()

در اینجا ما یکی از محبوب ترین مثال ها را داریم که نحوه کار این روش را نشان می دهد. فرض کنید ما یک فروشگاه، یک تولید کننده و یک مصرف کننده داریم. سازنده برخی از محصولات تولیدی را به فروشگاه منتقل می کند و پس از آن مصرف کننده می تواند آنها را تحویل بگیرد. اجازه دهید تولیدکننده به ترتیب 8 کالا تولید کند، مصرف کننده باید همه آنها را بخرد. اما در عین حال نمی توان بیش از 6 قلم کالا به طور همزمان در انبار باشد. برای حل این مشکل از متد ()water و notify() استفاده می کنیم . بیایید سه کلاس را تعریف کنیم: Market ، Manufacturer و Client . متد Manufacturer در run() 8 محصول را با استفاده از متد put() خود به شی Market اضافه می کند . کلاینت در متد run() در یک حلقه متد get شی Market را برای دریافت این محصولات فراخوانی می کند. متدهای put و get کلاس Market همگام هستند. برای پیگیری حضور کالاها در کلاس Market ، مقدار متغیر آیتم را بررسی می کنیم. متد get() برای بدست آوردن یک محصول فقط در صورتی باید فعال شود که حداقل یک محصول وجود داشته باشد. بنابراین در روش get بررسی می کنیم که آیا محصول موجود نیست. اگر آیتم در دسترس نباشد، متد wait() فراخوانی می شود. این متد مانیتور شی Market را آزاد می کند و متد get را مسدود می کند تا زمانی که متد notify() در همان مانیتور فراخوانی شود. هنگامی که یک آیتم در متد put() اضافه می شود و () notify فراخوانی می شود، متد get() مانیتور را دریافت می کند. پس از آن، مشتری ما یک مورد دریافت می کند. برای انجام این کار، یک پیام نمایش داده می شود و مقدار مورد کاهش می یابد. در نهایت، فراخوانی متد notify() به متد put() سیگنال می دهد تا ادامه یابد. در متد ()put ، منطق مشابه کار می‌کند، فقط حالا اگر بیش از 6 محصول در بازار وجود نداشته باشد، متد put() باید کار کند .
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();
   }
}
در اینجا با استفاده از wait() در متد get() منتظر هستیم تا Manufacturer آیتم جدیدی اضافه کند. و بعد از افزودن، notify() را فراخوانی می کنیم ، مثل اینکه می گوییم یک مکان در Warehouse رایگان شده است و می توانید تعداد بیشتری اضافه کنید. در متد put() با استفاده از wait() منتظر آزاد شدن فضا در Warehouse هستیم . پس از خالی شدن فضا، آیتم را اضافه می کنیم، notify() رشته را شروع می کند و Client می تواند آیتم را انتخاب کند. این هم خروجی برنامه ما:
سازنده 1 مورد دیگر اضافه کرده است ... اکنون 1 مورد در انبار وجود دارد سازنده 1 مورد دیگر اضافه کرده است ... اکنون 2 مورد در انبار وجود دارد سازنده 1 مورد دیگر اضافه کرده است ... اکنون 3 مورد در انبار وجود دارد. اضافه شد 1 مورد دیگر... اکنون 4 مورد در انبار وجود دارد. 1 عدد... تعداد اقلام در انبار مارکت... 5 مشتری 1 عدد خریده است... تعداد اقلام در انبار مارکت... 4 مشتری 1 عدد خریداری کرده است... تعداد اقلام در انبار مارکت... 3 یک مشتری 1 قلم خرید ... تعداد اقلام در انبار مارکت ... 2 مشتری 1 کالا خریده است ... تعداد اقلام در انبار مارکت ... 1 مشتری 1 قلم خرید ... تعداد اقلام در انبار مارکت ... 0 تولید کننده 1 مورد دیگر اضافه کرده است ... اکنون 1 مورد در انبار وجود دارد سازنده 1 مورد دیگر ... اکنون 2 کالا در انبار وجود دارد مشتری 1 مورد خریداری کرده است ... تعداد اقلام در انبار بازار ... 1 مشتری 1 کالا خریده است ... تعداد اقلام در انبار مارکت ... 0 فرآیند با کد خروجی تمام شد 0
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION