“สวัสดี อามีโก้!”

"สวัสดี ริชิ!"

"ฉันจะแนะนำคุณเกี่ยวกับเมธอดwait , alert , และalertAllของคลาส Object"

"วันนี้เราจะทำความคุ้นเคยกับพวกเขา แต่เราจะกลับมาใหม่ในภายหลังและใช้เวลากับเรื่องนี้ให้มากขึ้น"

"ตกลง."

"วิธีการเหล่านี้ถูกประดิษฐ์ขึ้นโดยเป็นส่วนหนึ่งของกลไกการซิงโครไนซ์เธรด"

"ฉันขอเตือนคุณว่า Java มีกลไกในตัวสำหรับควบคุมการเข้าถึงทรัพยากรที่ใช้ร่วมกัน (อ็อบเจ็กต์) จากเธรดต่างๆ เธรดสามารถประกาศว่าอ็อบเจ็กต์ไม่ว่าง และเธรดอื่นๆ จะต้องรอจนกว่าอ็อบเจ็กต์ไม่ว่างจะถูกปล่อย "

"ฉันจำได้ คุณทำอย่างนั้นโดยใช้ คีย์เวิร์ด ที่ซิงโครไนซ์"

"ถูกต้อง โดยปกติแล้ว รหัสจะมีลักษณะดังนี้:"

public void print()
{
 Object monitor = getMonitor();
 synchronized(monitor)
 {
  System.out.println("text");
 }
}

“จำวิธีการทำงานได้ไหม”

"ใช่ ถ้าเธรดสองเธรดเรียกใช้เมธอด print() พร้อมกัน หนึ่งในนั้นจะเข้าสู่บล็อกที่ระบุว่าซิงโครไนซ์และล็อคจอภาพ ซึ่งทำให้เธรดที่สองจะรอจนกว่ามอนิเตอร์จะถูกปล่อย"

"ถูกต้อง เมื่อเธรดเข้าสู่บล็อกที่ระบุว่าซิงโครไนซ์แล้ว วัตถุมอนิเตอร์จะถูกทำเครื่องหมายว่าไม่ว่าง และเธรดอื่นๆ จะถูกบังคับให้รอจนกว่าออบเจกต์มอนิเตอร์จะถูกปล่อย วัตถุมอนิเตอร์เดียวกันนี้สามารถนำไปใช้ในส่วนต่างๆ ของโปรแกรมได้ "

“ว่าแต่ ทำไมคุณถึงเลือกผู้ตรวจสอบชื่อล่ะ”

"จอภาพคือสิ่งที่คุณมักจะเรียกว่าวัตถุที่เก็บสถานะไม่ว่างหรือไม่ว่าง"

"และนี่คือที่มาของวิธีการรอและแจ้งเตือน "

"จริงๆแล้วนี่เป็นเพียงสองวิธีเท่านั้น ส่วนวิธีอื่นๆเป็นเพียงการดัดแปลงจากวิธีการเหล่านี้"

"ตอนนี้เรามาทำความเข้าใจกันว่าวิธีการรอคืออะไรและเหตุใดเราจึงต้องใช้ "

"บางครั้งมีสถานการณ์ในโปรแกรมที่เธรดเข้าสู่บล็อกของรหัสที่ซิงโครไนซ์และล็อคจอภาพ แต่ไม่สามารถดำเนินการต่อไปได้เนื่องจากไม่มีข้อมูลบางอย่าง ตัวอย่างเช่น ไฟล์ที่ต้องประมวลผลยังดาวน์โหลดไม่เสร็จหรือ อะไรแบบนั้น."

"เราแค่รอให้ดาวน์โหลดไฟล์ คุณสามารถตรวจสอบได้โดยใช้การวนซ้ำ หากไฟล์ยังไม่ได้ดาวน์โหลด ให้พักเครื่องประมาณหนึ่งวินาที แล้วตรวจสอบอีกครั้งจนกว่าจะดาวน์โหลด"

"อะไรประมาณนี้:"

while(!file.isDownloaded())
{
 Thread.sleep(1000);
}
processFile(file);

"แต่ในกรณีของเรา การรอประเภทนี้มีค่าใช้จ่ายสูงเกินไป เนื่องจากเธรดของเราล็อกจอภาพไว้ เธรดอื่นๆ จึงถูกบังคับให้รอด้วย แม้ว่าอาจมีข้อมูลที่ต้องการอยู่แล้วก็ตาม"

"เมธอดwait()ถูกคิดค้นขึ้นเพื่อแก้ปัญหานี้ เมธอดนี้ทำให้เธรดคลายมอนิเตอร์ จากนั้น «หยุดทำงาน» เธรด

"คุณสามารถเรียกใช้เมธอดการรอของออบเจกต์มอนิเตอร์เมื่อมอนิเตอร์ไม่ว่าง เช่น ภายในบล็อกซิงโครไนซ์เท่านั้น เมื่อสิ่งนี้เกิดขึ้น เธรดจะหยุดทำงานชั่วคราว และมอนิเตอร์จะถูกปล่อยเพื่อให้เธรดอื่นๆ สามารถใช้งานได้"

"มีบ่อยครั้งที่เธรดจะเข้าสู่ บล็อก ที่ซิงโครไนซ์และรอสาย

"จากนั้นเธรดที่สองจะเข้ามาและถูกระงับ จากนั้นเธรดที่สาม และอื่นๆ"

"แล้วเธรดจะกลับมาทำงานต่อได้อย่างไร"

"สำหรับสิ่งนั้น มีวิธีที่สอง: แจ้งเตือน"

"คุณสามารถเรียกใช้เมธอด alert / alertAll ของออบเจ็กต์มอนิเตอร์ได้ เมื่อมอนิเตอร์ไม่ว่าง เช่น ภายในบล็อกที่ซิงโครไนซ์ เท่านั้น เมธอด alertAllจะปลุกเธรดทั้งหมดที่กำลังรอออบเจกต์มอนิเตอร์นี้อยู่"

"เมธอด การ แจ้ง 'ยกเลิกการตรึง' หนึ่งเธรดแบบสุ่ม แต่เมธอดการแจ้งทั้งหมดจะยกเลิกการตรึงเธรด «แช่แข็ง» ทั้งหมดของมอนิเตอร์นี้"

"น่าสนใจมาก ขอบคุณ ฤๅษี"

"นอกจากนี้ยังมีการดัดแปลงของ wait() วิธีการ:"

วิธีการรอ () คำอธิบาย
void wait(long timeout)
เธรด «ค้าง» แต่โดยอัตโนมัติ «เลิกค้าง» หลังจากรอจำนวนมิลลิวินาทีที่ส่งผ่านไปยังเมธอดเป็นอาร์กิวเมนต์
void wait(long timeout, int nanos)
เธรด «ค้าง» แต่โดยอัตโนมัติ «เลิกค้าง» หลังจากรอจำนวนนาโนวินาทีที่ส่งผ่านไปยังเมธอดเป็นอาร์กิวเมนต์

"เราเรียกสิ่งนี้ว่าการรอแบบหมดเวลา วิธีการทำงานเหมือนการรอปกติ แต่ถ้าเลยเวลาที่กำหนดไปแล้วและเธรดไม่ได้รับการปลุก มันจะปลุกเอง"