“สวัสดี อามีโก้!”
"สวัสดี ริชิ!"
"ฉันจะแนะนำคุณเกี่ยวกับเมธอด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() วิธีการ:"
วิธีการรอ () | คำอธิบาย |
---|---|
|
เธรด «ค้าง» แต่โดยอัตโนมัติ «เลิกค้าง» หลังจากรอจำนวนมิลลิวินาทีที่ส่งผ่านไปยังเมธอดเป็นอาร์กิวเมนต์ |
|
เธรด «ค้าง» แต่โดยอัตโนมัติ «เลิกค้าง» หลังจากรอจำนวนนาโนวินาทีที่ส่งผ่านไปยังเมธอดเป็นอาร์กิวเมนต์ |
"เราเรียกสิ่งนี้ว่าการรอแบบหมดเวลา วิธีการทำงานเหมือนการรอปกติ แต่ถ้าเลยเวลาที่กำหนดไปแล้วและเธรดไม่ได้รับการปลุก มันจะปลุกเอง"
GO TO FULL VERSION