หลังจากดำเนินการ wait () เธรดจะรอนานเท่าใดหากไม่ได้รับการแจ้งเตือนจากเธรดอื่น
ในตัวอย่างด้านล่างเนื่องจากเธรดหลักไม่ได้รับการแจ้งเตือนจากเธรดย่อยจึงควรรอตลอดไป แต่เธรดหลักกำลังดำเนินการและผลลัพธ์ของตัวอย่างด้านล่างคือ:
c
l
total: 19900
เหตุใดเธรดหลักจึงถูกเรียกใช้งาน
public class ThreadX extends Thread {
static int total = 0;
public void run() {
synchronized (this) {
for (int i = 0; i < 200; i++) {
total = total + i;
}
System.out.println("c");
}
}
public static void main(String[] args) throws InterruptedException {
ThreadX t = new ThreadX();
t.start();
synchronized (t) {
t.wait();
System.out.println("l");
}
System.out.println("total: " + total);
}
}
คำตอบ
ตอบคำถาม - ร่างกาย
ตรวจสอบThread#join(long):
[... ] เมื่อเธรดสิ้นสุด
this.notifyAll
เมธอดจะถูกเรียกใช้ [... ]
สังเกตว่าThread#join()
เรียกใช้ฟังก์ชันนั้นด้วย0
ซึ่งหมายถึงตลอดไป
[... ] การหมดเวลาของ 0 หมายถึงการรอตลอดไป
ดังนั้นในกรณีของคุณที่นี่t
เพียงแค่เรียกร้องเมื่อมันสิ้นสุดลงซึ่งแจ้งหลักหัวข้อที่กำลังรอnotifyAll
t
พฤติกรรมที่ไม่เข้าใจง่ายนี้เป็นสาเหตุที่พวกเขาเขียนสิ่งต่อไปนี้ในเอกสารประกอบ:
ก็จะแนะนำว่าการใช้งานที่ไม่ได้ใช้
wait
,notify
หรือnotifyAll
ในThread
กรณี
ตอบคำถาม - ชื่อเรื่อง
ตรวจสอบObject#wait(หรือJLS (17.2.1. รอ) ):
เธรดสามารถปลุกได้โดยไม่ได้รับการแจ้งเตือนถูกขัดจังหวะหรือหมดเวลาซึ่งเรียกว่าการปลุกแบบปลอม ๆ แม้ว่าสิ่งนี้จะไม่ค่อยเกิดขึ้นในทางปฏิบัติ แต่แอปพลิเคชันจะต้องป้องกันโดยการทดสอบเงื่อนไขที่น่าจะทำให้เธรดถูกปลุกและรอต่อไปหากเงื่อนไขไม่เป็นที่พอใจ
ดังนั้นเธรดใน Java จึงสามารถปลุกได้ตลอดเวลา การปลุกแบบปลอม ๆ ไม่น่าจะเกิดขึ้นมากนักแต่ก็สามารถเกิดขึ้นได้