เมธอด wait, notify และ notifyAll เป็นเมธอดเนทีฟขั้นสุดท้ายของคลาส Object ดังนั้นเมธอดเหล่านี้จึงไม่สามารถแทนที่ด้วยคลาสย่อยได้ คลาส Object จึงเป็นคลาสระดับสูงของคลาสทั้งหมด ดังนั้นจึงมีรูปแบบการเรียก wait และวิธีการอื่นในโปรแกรมสามรูปแบบดังต่อไปนี้
คัดลอกรหัสรหัส ดังต่อไปนี้:
รอ();//วิธีที่ 1:
this.wait();//วิธีที่ 2:
super.wait();//วิธีที่ 3
เป็นโมฆะแจ้งทั้งหมด()
เลิกบล็อกเธรดทั้งหมดที่เรียกใช้วิธีการรอบนวัตถุนี้ วิธีนี้สามารถเรียกได้ภายในวิธีการซิงโครไนซ์หรือบล็อกซิงโครไนซ์เท่านั้น ถ้าเธรดปัจจุบันไม่ใช่ตัวยึดล็อค วิธีการนี้จะส่ง IllegalMonitorStateException
แจ้งเป็นโมฆะ()
สุ่มเลือกเธรดที่เรียกวิธีการรอบนวัตถุเพื่อปลดบล็อค วิธีนี้สามารถเรียกได้ภายในวิธีการซิงโครไนซ์หรือบล็อกซิงโครไนซ์เท่านั้น ถ้าเธรดปัจจุบันไม่ใช่ตัวยึดล็อค วิธีการนี้จะส่ง IllegalMonitorStateException
เป็นโมฆะรอ ()
ทำให้เธรดเข้าสู่สถานะรอจนกว่าเธรดอื่นจะตื่นขึ้นผ่าน notify() หรือ notifyAll วิธีนี้สามารถเรียกได้ภายในวิธีการซิงโครไนซ์เท่านั้น ถ้าเธรดปัจจุบันไม่ใช่ตัวยึดล็อค วิธีการนี้จะส่ง IllegalMonitorStateException
รอเป็นโมฆะ (มิลลิวินาทียาว) และรอเป็นโมฆะ (มิลลิวินาทียาว, int nanos)
ทำให้เธรดเข้าสู่สถานะรอจนกว่าจะได้รับแจ้งหรือผ่านพ้นเวลาที่กำหนด วิธีการเหล่านี้สามารถเรียกได้ภายในวิธีการซิงโครไนซ์เท่านั้น ถ้าเธรดปัจจุบันไม่ใช่ตัวยึดล็อค วิธีการนี้จะส่ง IllegalMonitorStateException
Object.wait(), Object.notify() และ Object.notifyall() จะต้องเขียนภายในวิธีการซิงโครไนซ์หรือภายในบล็อกการซิงโครไนซ์ เนื่องจากวิธีการเหล่านี้ต้องการให้เธรดที่กำลังเรียกใช้วิธีการ object.wait() เป็นเจ้าของ วัตถุ ล็อควัตถุ แม้ว่าคุณจะทราบแน่ชัดว่าเธรดบริบทปัจจุบันเป็นเจ้าของการล็อกอ็อบเจ็กต์ คุณไม่สามารถเขียนคำสั่งเช่น object.wait() ในบริบทปัจจุบันได้ ชอบ:
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ edu.sjtu.erplab.ObjectTest;
คลาส A
-
โมฆะที่ซิงโครไนซ์สาธารณะ printThreadInfo() พ่น InterruptedException
-
เธรด t=Thread.currentThread();
System.out.println("ThreadID:"+t.getId()+", ชื่อเธรด:"+t.getName());
-
-
ObjectWaitTest คลาสสาธารณะ {
โมฆะคงสาธารณะ main (String args [])
-
A a=ใหม่ A();
//เนื่องจากเมธอด printThreadInfo() ส่ง InterruptedException จึงต้องใช้บล็อก try-catch ที่นี่
พยายาม {
ก.printThreadInfo();
ก.รอ();
} จับ (InterruptedException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
-
-
เมื่อรันโปรแกรมจะรายงานข้อผิดพลาดและผลลัพธ์จะเป็นดังนี้:
ThreadID:1, ThreadName:main
ข้อยกเว้นในเธรด "main" java.lang.IllegalMonitorStateException
ที่ java.lang.Object.wait (วิธีดั้งเดิม)
ที่ java.lang.Object.wait (Object.java:485)
ที่ edu.sjtu.erplab.ObjectTest.ObjectWaitTest.main (ObjectWaitTest.java:24)
วิธีเขียนที่ถูกต้องควรเป็น
คัดลอกรหัสรหัส ดังต่อไปนี้:
แพ็คเกจ edu.sjtu.erplab.ObjectTest;
คลาส A
-
โมฆะที่ซิงโครไนซ์สาธารณะ printThreadInfo() พ่น InterruptedException
-
เธรด t=Thread.currentThread();
System.out.println("ThreadID:"+t.getId()+", ชื่อเธรด:"+t.getName());
// this.wait(); // รอต่อไป
this.wait(1,000);//รอ 1,000ms
// super.wait(1,000);
-
-
ObjectWaitTest คลาสสาธารณะ {
โมฆะคงสาธารณะ main (String args [])
-
A = ใหม่ A();
//เนื่องจากเมธอด printThreadInfo() ส่ง InterruptedException จึงต้องใช้บล็อก try-catch ที่นี่
พยายาม {
ก.printThreadInfo();
//a.รอ();
} จับ (InterruptedException e) {
// TODO บล็อก catch ที่สร้างขึ้นอัตโนมัติ
e.printStackTrace();
-
เธรด t=Thread.currentThread();
System.out.println("ThreadID:"+t.getId()+", ชื่อเธรด:"+t.getName());
-
-