เธรดสัมปทาน: ผลผลิต ()
วัตถุประสงค์ของผลผลิต () คือการให้เข้ามามันสามารถอนุญาตให้เธรดปัจจุบันเข้าสู่ "สถานะพร้อม" จาก "สถานะการทำงาน" เพื่อให้เธรดรออื่นที่มีลำดับความสำคัญเดียวกันสามารถรับสิทธิ์การดำเนินการ; อย่างไรก็ตามไม่สามารถรับประกันได้ว่าหลังจากการเรียกเธรดปัจจุบันให้ผลผลิต () เธรดอื่น ๆ ที่มีลำดับความสำคัญเดียวกันจะได้รับสิทธิ์ในการดำเนินการอย่างแน่นอน อาจเป็นไปได้ว่าเธรดปัจจุบันจะเข้าสู่ "สถานะการรัน" และยังคงทำงานต่อไป!
ตัวอย่าง:
คลาส Threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public synchronized void run () {สำหรับ (int i = 0; i <10; i ++) {system.out.printf ("%s [%d]:%d/n", getName (), this.getPriority (), i); // เมื่อฉันถูกหารด้วย 4 ให้โทรหาถ้า (i%4 == 0) เธรด yield (); }}} ระดับสาธารณะให้ผลผลิต {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada t1 = threada ใหม่ ("t1"); threada t2 = threada ใหม่ ("t2"); t1.start (); t2.start (); - (ครั้งเดียว) ผลการดำเนินการ:
T1 [5]: 0T2 [5]: 0T1 [5]: 1T1 [5]: 2T1 [5]: 3T1 [5]: 4T1 [5]: 5T1 [5]: 6T1 [5]: 7T1 [5]: 8T1 [5]: 9T2 [5]: 1T2 [5] [5]: 6T2 [5]: 7T2 [5]: 8T2 [5]: 9
ผลลัพธ์คำอธิบาย:
เมื่อ "เธรด T1" สามารถเป็นจำนวนเต็มได้ 4 จะไม่เปลี่ยนเป็น "เธรด T2" สิ่งนี้แสดงให้เห็นว่าถึงแม้ว่าผลผลิต () สามารถอนุญาตให้เธรดเข้าสู่ "สถานะพร้อม" จาก "การเรียกใช้สถานะ" แต่ก็ไม่จำเป็นต้องอนุญาตให้เธรดอื่นได้รับสิทธิ์ในการดำเนินการ CPU (เช่นเธรดอื่น ๆ เข้าสู่ "สถานะการทำงาน") แม้ว่า "เธรดอื่น ๆ " นี้จะมีลำดับความสำคัญเช่นเดียวกับเธรดที่เรียกว่าอัตราผลตอบแทน ()
การเปรียบเทียบผลผลิต () และรอ ():
เรารู้ว่าฟังก์ชั่นของการรอคอย () คือการอนุญาตให้เธรดปัจจุบันเข้าสู่สถานะ "รอ (บล็อก) จาก" สถานะการทำงาน "และยังปล่อยล็อคการซิงโครไนซ์ฟังก์ชั่นของผลผลิต () จะให้ซึ่งจะทำให้เธรดปัจจุบันออกจาก" สถานะการทำงาน "ความแตกต่างของพวกเขาคือ:
(1) รอ () คือการให้เธรดป้อนสถานะ "รอ (บล็อก)" จาก "สถานะการทำงาน" ในขณะที่ไม่ให้ผลผลิต () คือการให้เธรดป้อน "สถานะพร้อม" จาก "สถานะการทำงาน"
(2) WAIT () คือการล็อคการซิงโครไนซ์ที่จะปล่อยออกจากวัตถุที่เก็บไว้ในขณะที่วิธีการให้ () จะไม่ปล่อยล็อค
ตัวอย่างต่อไปนี้แสดงให้เห็นว่าอัตราผลตอบแทน () จะไม่ปล่อยล็อค:
ชั้นเรียนสาธารณะ FieldLocktest {วัตถุคงที่ส่วนตัว obj = วัตถุใหม่ (); โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada t1 = threada ใหม่ ("t1"); threada t2 = threada ใหม่ ("t2"); t1.start (); t2.start (); } ชั้นเรียนแบบคงที่ threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public void run () {// รับซิงโครไนซ์ (obj) {สำหรับ (int i = 0; i <10; i ++) {system.out.printf ("%s [%d]:%d/n", this.getName () // เมื่อฉันถูกหารด้วย 4 ให้โทรหาถ้า (i%4 == 0) เธรด yield (); - (ครั้งเดียว) ผลลัพธ์:
T1 [5]: 0T1 [5]: 1T1 [5]: 2T1 [5]: 3T1 [5]: 4T1 [5]: 5T1 [5]: 6T1 [5]: 7T1 [5]: 8T1 [5]: 9T2 [5]: 0T2 [5]: 1T2 [5] [5]: 6T2 [5]: 7T2 [5]: 8T2 [5]: 9
ผลลัพธ์คำอธิบาย:
สองเธรด T1 และ T2 เริ่มต้นใน Main Thread Main T1 และ T2 จะอ้างถึงการล็อคการซิงโครไนซ์ของวัตถุเดียวกันใน Run () นั่นคือซิงโครไนซ์ (OBJ) ในระหว่างการดำเนินการ T1 แม้ว่ามันจะเรียกเธรด yield (); T2 จะไม่ได้รับสิทธิ์ในการดำเนินการของ CPU เพราะ T1 ไม่ปล่อย "ล็อคแบบซิงโครนัสที่จัดขึ้นโดย OBJ"!
ด้ายนอนหลับ: นอนหลับ ()
sleep () ถูกกำหนดไว้ใน Thread.java
ฟังก์ชั่นของ Sleep () คือการปล่อยให้ด้ายปัจจุบันนอนหลับนั่นคือเธรดปัจจุบันจะเข้าสู่ "สถานะการทำงาน" ไปยังสถานะ "การนอนหลับ (บล็อก)" sleep () จะระบุเวลานอนหลับและเวลานอนด้ายจะมากกว่า/เท่ากับเวลานอน เมื่อเธรดถูกปลุกอีกครั้งมันจะเปลี่ยนจาก "สถานะการปิดกั้น" เป็น "สถานะพร้อม" รอให้ CPU ถูกกำหนดให้ดำเนินการ
ตัวอย่าง:
คลาส Threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public synchronized void run () {ลอง {สำหรับ (int i = 0; i <10; i ++) {system.out.printf (" %s: %d/n", this.getName (), i); // เมื่อฉันสามารถหารด้วย 4 นอนสำหรับ 100ms ถ้า (i%4 == 0) thread.sleep (100); }} catch (interruptedException e) {e.printStackTrace (); }}} คลาสสาธารณะ sleeptest {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {threada t1 = threada ใหม่ ("t1"); t1.start (); - ผลการทำงาน:
T1: 0T1: 1T1: 2T1: 3T1: 4T1: 5T1: 6T1: 7T1: 8T1: 9
ผลลัพธ์คำอธิบาย:
โปรแกรมค่อนข้างง่ายเริ่มเธรด T1 ใน Main Thread Main หลังจาก T1 เริ่มต้นขึ้นเมื่อการคำนวณ I ใน T1 สามารถหารได้ 4, T1 จะนอนหลับได้ 100 มิลลิวินาทีผ่าน Thread.sleep (100)
การเปรียบเทียบการนอนหลับ () และรอ ():
เรารู้ว่าฟังก์ชั่นของการรอคอย () คือการอนุญาตให้เธรดปัจจุบันเข้าสู่สถานะ "รอ (บล็อก) จาก" สถานะการรัน "และปล่อยล็อคการซิงโครไนซ์ฟังก์ชั่นของ Sleep () คือการให้เธรดปัจจุบันป้อน" สถานะการนอนหลับ (บล็อก) "จาก" สถานะการวิ่ง "
อย่างไรก็ตามรอ () ปล่อยล็อคการซิงโครไนซ์ของวัตถุในขณะที่ Sleep () ไม่ปล่อยล็อค
ตัวอย่างต่อไปนี้แสดงให้เห็นว่า sleep () จะไม่ปล่อยล็อค
คลาสสาธารณะ sleeplocktest {วัตถุคงที่ส่วนตัว obj = วัตถุใหม่ (); โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada t1 = threada ใหม่ ("t1"); threada t2 = threada ใหม่ ("t2"); t1.start (); t2.start (); } ชั้นเรียนแบบคงที่ threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public void run () {// รับการล็อคการซิงโครไนซ์ของ obj object synchronized (obj) {ลอง {สำหรับ (int i = 0; i <10; i ++) {system.out.printf (" %s: %d/n", this.getName (), i); // เมื่อฉันสามารถหารด้วย 4 นอนสำหรับ 100ms ถ้า (i%4 == 0) thread.sleep (100); }} catch (interruptedException e) {e.printStackTrace (); - ผลการทำงาน:
T1: 0T1: 1T1: 2T1: 3T1: 4T1: 5T1: 6T1: 7T1: 8T1: 9T2: 0T2: 1T2: 2T2: 3T2: 4T2: 5T2: 6T2: 7T2: 8T2: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9: 9
ผลลัพธ์คำอธิบาย:
สองเธรด T1 และ T2 เริ่มต้นใน Main Thread Main T1 และ T2 จะอ้างถึงการล็อคการซิงโครไนซ์ของวัตถุเดียวกันใน Run () นั่นคือซิงโครไนซ์ (OBJ) ในระหว่างการทำงานของ T1 แม้ว่ามันจะเรียก Thread.sleep (100); T2 จะไม่ได้รับสิทธิ์ในการดำเนินการของ CPU เพราะ T1 ไม่ปล่อย "ล็อคแบบซิงโครนัสที่จัดขึ้นโดย OBJ"!
โปรดทราบว่าหากเราแสดงความคิดเห็นออกซิงโครไนซ์ (OBJ) และดำเนินการโปรแกรมอีกครั้ง T1 และ T2 สามารถเปลี่ยนไปใช้กันได้ ต่อไปนี้เป็นซอร์สโค้ดหลังจากการปรับความคิดเห็นที่ซิงโครไนซ์ (OBJ):
คลาสสาธารณะ sleeplocktest {วัตถุคงที่ส่วนตัว obj = วัตถุใหม่ (); โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada t1 = threada ใหม่ ("t1"); threada t2 = threada ใหม่ ("t2"); t1.start (); t2.start (); } ชั้นเรียนแบบคงที่ threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public void run () {// รับการล็อคการซิงโครไนซ์ของ obj object // ซิงโครไนซ์ (obj) {ลอง {สำหรับ (int i = 0; i <10; i ++) {system.out.printf (" %s: %d/n", this.getName (), i); // เมื่อฉันสามารถหารด้วย 4 นอนสำหรับ 100ms ถ้า (i%4 == 0) thread.sleep (100); }} catch (interruptedException e) {e.printStackTrace (); -