במאמר זה, נסתכל על שיטת wait() לשליטה בשרשור, ואת המתודות notify() / notifyAll() . שיטות אלו מוגדרות במחלקה הבסיסית java.lang.Object ובהתאם לכך, מנגנוני ההורשה שנמצאים ב-Java מספקים את השיטות הללו לכל המחלקות. כלומר, כשאתה יוצר מחלקה משלך והאובייקטים שלה, אתה תמיד יכול לקרוא לשיטות האלה.
כיצד פועלות המתודות wait() ו-notify()/notifyAll()?
- wait() . בקיצור, שיטה זו משחררת את המוניטור ומכניסה את השרשור הקורא למצב המתנה עד שרשור אחר יקרא לשיטת notify() / notifyAll() ;
- להודיע() . ממשיך את העבודה של שרשור ששיטת ה-wait() שלו נקראה בעבר;
- השיטה notifyAll() מחדשת את כל השרשורים שנקראו בעבר לשיטת wait() שלהם.
-
המתנה של ריק מקורי אחרון ציבורי (זמן קצוב ארוך Millis) זורק InterruptedException ; זה גורם לשרשור הנוכחי להמתין עד שהוא מתעורר. בדרך כלל זה קורה על ידי קבלת הודעה או הפרעה, או עד שחלפה כמות מסוימת של זמן אמת.
-
public final void wait() זורק InterruptedException . לא במקרה כתבנו שיטה ללא פרמטרים בתור השנייה. למעשה, אם אתה מסתכל על הקוד שלו, הוא מתייחס לגרסה הראשונה של השיטה, יש לו רק את הארגומנט 0L.
-
המתנה סופית ציבורית (פסק זמן ארוך, ננו אינט.) . גורם לשרשור הנוכחי להמתין עד שהוא מתעורר, בדרך כלל על ידי קבלת הודעה או הפרעה, או עד שחלפה כמות מסוימת של זמן אמת.
דוגמה לשיטת 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
GO TO FULL VERSION