CodeGym /בלוג Java /Random-HE /Wait() שיטה ב-Java
John Squirrels
רָמָה
San Francisco

Wait() שיטה ב-Java

פורסם בקבוצה
במאמר זה, נסתכל על שיטת wait() לשליטה בשרשור, ואת המתודות notify() / notifyAll() . שיטות אלו מוגדרות במחלקה הבסיסית java.lang.Object ובהתאם לכך, מנגנוני ההורשה שנמצאים ב-Java מספקים את השיטות הללו לכל המחלקות. כלומר, כשאתה יוצר מחלקה משלך והאובייקטים שלה, אתה תמיד יכול לקרוא לשיטות האלה.

כיצד פועלות המתודות wait() ו-notify()/notifyAll()?

  • wait() . בקיצור, שיטה זו משחררת את המוניטור ומכניסה את השרשור הקורא למצב המתנה עד שרשור אחר יקרא לשיטת notify() / notifyAll() ;
  • להודיע() . ממשיך את העבודה של שרשור ששיטת ה-wait() שלו נקראה בעבר;
  • השיטה notifyAll() מחדשת את כל השרשורים שנקראו בעבר לשיטת wait() שלהם.
כעת בואו נסתכל מקרוב על שיטת wait() . המחלקה Object מכילה שלוש אפשרויות לשיטה זו:
  • המתנה של ריק מקורי אחרון ציבורי (זמן קצוב ארוך Millis) זורק InterruptedException ; זה גורם לשרשור הנוכחי להמתין עד שהוא מתעורר. בדרך כלל זה קורה על ידי קבלת הודעה או הפרעה, או עד שחלפה כמות מסוימת של זמן אמת.

  • public final void wait() זורק InterruptedException . לא במקרה כתבנו שיטה ללא פרמטרים בתור השנייה. למעשה, אם אתה מסתכל על הקוד שלו, הוא מתייחס לגרסה הראשונה של השיטה, יש לו רק את הארגומנט 0L.

  • המתנה סופית ציבורית (פסק זמן ארוך, ננו אינט.) . גורם לשרשור הנוכחי להמתין עד שהוא מתעורר, בדרך כלל על ידי קבלת הודעה או הפרעה, או עד שחלפה כמות מסוימת של זמן אמת.

השיטה wait() נועדה להשעות את השרשור הקורא. מה זה אומר? שיטות אלו שייכות לכיתה. בהתבסס על המחלקה, אתה יוצר אובייקט. אובייקטים קיימים בחלק מהשרשורים. כלומר, אובייקטים נוצרים בחוטים מסוימים. בשרשור בו האובייקט הזה עובד, אם תקרא בו wait() זה יוביל לכך שהשרשור הזה ייפסק. האובייקט עצמו פועל כמעין מוניטור. מה זה? ברור שניתן ליצור אובייקטים שונים וכולם יכילו את שיטת wait() . ישנה הבנה איזה אובייקט גרם לעצירה של חוט מסוים. השרשור נעצר ויחכה כל עוד הוא כתוב בפרמטר. ואז זה יתחיל. השרשור הזה לא יכול להתחיל בעצמו. כדי לחדש את העבודה, ישנן שיטות הודע והודיע ​​כל. קריאה ל- notify() או notifyAll() חייבת להפעיל שרשור אחר. עם wait() , אתה יכול לעצור שרשורים מרובים, ולהתחיל את כל השרשורים עם notifyAll() . אם מספר שרשורים נעצרו ונקרא notify() , אי אפשר לדעת בדיוק איזה שרשור יחדש את השיטה הזו. אם אין שרשורים ממתינים בשיטת wait() אז שום דבר לא קורה כשנקרא notify() או notifyAll() . שרשור יכול לקרוא לשיטות wait() או notify() על אובייקט מסוים רק אם יש לו כרגע נעילה על האובייקט הזה. wait() , notify() ו- notifyAll() צריכים להיקרא רק מקוד מסונכרן.

דוגמה לשיטת Wait()

כאן יש לנו את אחת הדוגמאות הפופולריות ביותר שממחישות כיצד השיטה עובדת. נניח שיש לנו חנות, יצרן וצרכן. היצרן מעביר כמה מוצרי ייצור לחנות, ולאחר מכן הצרכן יכול לקחת אותם. תן ליצרן לייצר 8 מוצרים, בהתאמה, הצרכן חייב לקנות את כולם. אך יחד עם זאת, לא יותר מ-6 פריטים יכולים להיות במחסן בו זמנית. כדי לפתור בעיה זו, אנו משתמשים בשיטות wait() ו- notify() . הבה נגדיר שלוש מחלקות : שוק , יצרן ולקוח . השיטה Manufacturer in the run() מוסיפה 8 מוצרים לאובייקט Market באמצעות שיטת put() שלו . הלקוח בשיטת run() בלולאה קורא לשיטת get של אובייקט Market כדי לקבל את המוצרים הללו. שיטות ה-put and get של מחלקת Market מסונכרנות. כדי לעקוב אחר נוכחות הסחורה במחלקת השוק , אנו בודקים את הערך של משתנה הפריט. השיטה get() להשגת מוצר צריכה לפעול רק אם יש לפחות מוצר אחד. לכן בשיטת get אנחנו בודקים אם המוצר חסר. אם הפריט אינו זמין, השיטה wait() נקראת. שיטה זו משחררת את המוניטור של אובייקט Market וחוסמת את שיטת get עד שהמתודה notify() נקראת באותו מוניטור. כאשר פריט מתווסף בשיטת put() ונקרא notify() , השיטה get() מקבלת את המוניטור. לאחר מכן, הלקוח שלנו מקבל פריט. לשם כך, מוצגת הודעה, וערך הפריט מופחת. לבסוף, הקריאה לשיטת notify() מאותתת לשיטת put() להמשיך. בשיטת put() לוגיקה דומה עובדת, רק שכעת שיטת put() אמורה לעבוד אם אין יותר מ-6 מוצרים ב- Market .
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() אנו ממתינים שהיצרן יוסיף פריט חדש. ואחרי ההוספה, אנו מתקשרים ל-notify() , כאילו אומרים שמקום אחד הפך פנוי במחסן , ותוכל להוסיף עוד. בשיטת put() באמצעות wait() , אנו ממתינים לשחרור מקום ב- Warehouse . לאחר שהמקום פנוי, נוסיף את הפריט, notify() מתחיל את השרשור והלקוח יכול לאסוף את הפריט. להלן הפלט של התוכנית שלנו:
היצרן הוסיף 1 פריט נוסף... כעת יש 1 פריט במחסן היצרן הוסיף 1 פריט נוסף... כעת יש 2 פריטים במחסן היצרן הוסיף 1 פריט נוסף... כעת יש 3 פריטים במחסן. הוסיף 1 פריט נוסף... כעת יש 4 פריטים במחסן היצרן הוסיף 1 פריט נוסף... כעת יש 5 פריטים במחסן היצרן הוסיף 1 פריט נוסף... כעת יש 6 פריטים במחסן לקוח קנה 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