กลไกการขัดจังหวะเธรดให้วิธีการปลุกเธรดจากการรอการปิดกั้นพยายามที่จะขัดจังหวะโฟลว์การประมวลผลที่มีอยู่ของเธรดเป้าหมายและตอบสนองต่อคำสั่งใหม่ Java ทิ้งอิสรภาพนี้ให้กับนักพัฒนาและเราควรใช้ประโยชน์จากมันให้ดี
วันนี้เราจะพูดคุยเกี่ยวกับกลไกการขัดจังหวะของกระทู้ Java
กลไกการขัดจังหวะเธรดมีวิธีการที่มีการใช้งานทั่วไปสองประการ:
ปลุกเธรดจากการปิดกั้นการรอคอยและทำการประมวลผล "ควบคุมการขัดจังหวะ" ที่สอดคล้องกัน
พยายามแจ้งเธรดเป้าหมาย: โปรดขัดจังหวะกระแสการประมวลผลที่มีอยู่และตอบสนองต่อคำสั่งใหม่
ใช้จุดประสงค์แรกเป็นตัวอย่างโปรดดูรหัสต่อไปนี้:
ซิงโครไนซ์ (ล็อค) {ลอง {ในขณะที่ (! ตรวจสอบ ()) {lock.wait (1,000); }} catch (interruptedException e) {e.printStackTrace (); -รหัสนี้ใช้กลไกการรอ/แจ้งเตือนที่จัดทำโดย Java การดำเนินการเธรดของ lock.wait () จะบล็อก มีสามสถานการณ์ในการกู้คืนเธรดที่จะเรียกใช้
1. การหมดเวลา 1,000ms สิ้นสุดลงและรหัสถัดไปจะดำเนินการตามปกติ
2. เธรดอื่นดำเนินการรหัสต่อไปนี้เพื่อปลุกอย่างแข็งขัน
ซิงโครไนซ์ (ล็อค) {lock.notifyall (); // หรือ lock.notify ();}สิ่งนี้จะเรียกใช้รหัสถัดไปตามปกติ
3. เธรดอื่นที่ต้องรอคือ "ขัดจังหวะ"
// รับการอ้างอิงไปยังเธรดการรอเธรด a; a.interrupt ();
เธรด A นั่นคือ "ถูกขัดจังหวะ" จะโยนข้อยกเว้น interruptedException ที่ lock.wait ()
โดยสรุปคุณสามารถคิดว่า Object.wait () กำลังทำสิ่งเหล่านี้ภายใน:
บูลีน checktimeout = หมดเวลา> 0; เธรด current = thread.currentThread (); lock.addwaiter (ปัจจุบัน); ในขณะที่ (! current.isnotified ()) {ถ้า (current.isinterrupted ()) {current.learInterinted (); โยน InterruptedException ใหม่ (); } if (checktimeout) {ถ้า (หมดเวลา == 0) break; หมดเวลา-; -สิ่งนี้ไม่ถูกต้องอย่างสมบูรณ์เพราะการรอไม่ได้ใช้วิธีการ "การสำรวจที่วุ่นวาย" นี้เพื่อตรวจสอบ แต่ตรรกะของการตัดสินบิตธงนั้นถูกต้อง
เริ่มต้นด้วยการดำเนินการ "ขัดจังหวะด้วยตนเอง" ที่กล่าวถึงข้างต้น
// sun.nio.ch.interruptiblepublic อินเตอร์เฟสขัดจังหวะ {void interrupt (เธรด var1);} // java.lang.threadPrivate blocker ขัดจังหวะการผันผวนของวัตถุสุดท้าย blockerlock = วัตถุใหม่ (); โมฆะสาธารณะขัดจังหวะ () {ถ้า ( ซิงโครไนซ์ (blockerLock) {ขัดจังหวะ b = blocker; if (b! = null) {interrupt0 (); b.interrupt (นี่); กลับ; }} interrupt0 ();} // เพียงเพื่อตั้งค่าการขัดจังหวะการขัดจังหวะการขัดจังหวะ native interrupt0 ();จะเห็นได้ว่า thread.interrupt () ผู้ตัดสินครั้งแรกได้รับอนุญาตจากนั้นเรียกใช้ interrupt0 () เพื่อตั้งค่าการขัดจังหวะของเธรด หากเธรดปัจจุบันมีการขัดจังหวะของ NIO ก็จะโทรกลับ
โปรดทราบว่า interrupt0 () เพียงแค่ตั้งค่าสถานะการขัดจังหวะของเธรด
จะเกิดอะไรขึ้นเมื่อเธรดไม่ได้ปิดกั้นและไม่ได้อยู่ในพื้นที่ที่ไม่ได้ควบคุมโดยตรรกะของโปรแกรม Java เช่น Object.wait (), thread.oin (), thread.sleep ()? คำตอบคือไม่มีอะไรจะเกิดขึ้นและไม่ว่าเธรดจะถูกขัดจังหวะสามารถเป็นที่รู้จักโดยการตรวจสอบธงขัดจังหวะอย่างแข็งขัน
จะตรวจสอบได้อย่างไร? เธรดแสดงสองอินเทอร์เฟซ, thread.interrupted () และ thread.isinterrupted ()
// java.lang.Threadpublic boolean คงที่ขัดจังหวะ () {return currentThread (). isInterrupted (จริง);} บูลีนสาธารณะ isinterrupted () {return isinterrupted (เท็จ);} บูลีนส่วนตัวจะเห็นได้ว่าทั้งคู่พึ่งพา isinterrupted ภายใน (บูลีน) ซึ่งจะกลับมาว่าเธรดถูกขัดจังหวะและล้างธงขัดจังหวะตามต้องการ
เมื่อฟังก์ชั่นการเรียกบล็อกฟังก์ชั่น Java Library เครื่องหมายจะพุ่งเข้าหาการขัดจังหวะในการปิดกั้นลายเซ็นของแหล่งที่มาและต้องใช้การเขียนลองจับเพื่อจัดการการขัดจังหวะ
เมื่อบล็อกเธรดดังที่กล่าวไว้ข้างต้น Java จะตรวจสอบการตั้งค่าสถานะขัดจังหวะให้ล้างก่อนแล้วจึงโยน InterruptedException
// java.lang.ObjectPublic สุดท้ายเป็นโมฆะ Wait () พ่น InterruptedException {WAIT (0);} Public Public Native Native Wait (Long Timeout) โยน InterruptedException;หากเธรดได้รับการขัดจังหวะการรับรู้จากนั้นเรียกใช้รหัสที่จะโยนการบล็อกมันจะยังคงบล็อกเช่น "ไม่ว่า" เพราะ Java ล้างธงขัดจังหวะภายใน!
เรามักจะเขียนรหัสสามประเภทต่อไปนี้ที่จัดการกับการขัดจังหวะการรับรู้:
จัดการกับการขัดจังหวะการรับรู้ถึงชั้นบนสำหรับการประมวลผล
โมฆะสาธารณะ foo () พ่น InterruptedException {ซิงโครไนซ์ (ล็อค) {lock.wait (); -InterruptedException รีเซ็ตบิตอินเตอร์รัปต์
ลอง {ซิงโครไนซ์ (ล็อค) {lock.wait (); }} catch (interruptedException e) {thread.currentthread (). interrupt (); //หยุดพัก; -ทำงานของคุณให้เสร็จก่อนแล้วโยน InterruptedException อีกครั้ง
Public Void Bar () พ่น InterruptedException {InterruptedException IE = NULL; บูลีนเสร็จ = เท็จ; ในขณะที่ (! เสร็จแล้ว) {ซิงโครไนซ์ (ล็อค) {ลอง {lock.wait (); } catch (interruptedException e) {ie = e; ดำเนินการต่อ; }} ทำ = จริง; } ถ้า (เช่น! = null) {โยน ie; -หากเธรดไม่สนใจธงขัดจังหวะและ InterruptedException มันก็ยังทำงานได้ดี แต่นี่เป็นสิ่งที่ตรงกันข้ามกับความตั้งใจดั้งเดิมของเราในการออกแบบมัลติเธรด เราต้องการให้เธรดร่วมมือกันอย่างกลมกลืนและอย่างเป็นระเบียบเพื่อให้ได้ฟังก์ชั่นเฉพาะดังนั้นเธรดที่ควบคุมควรตอบสนองต่อการขัดจังหวะ และเราควรใช้ประโยชน์จากอิสรภาพที่เหลือไว้โดย Java ให้กับนักพัฒนา
ข้างต้นคือความรู้ที่เกี่ยวข้องทั้งหมดเกี่ยวกับกลไกการขัดจังหวะของกระทู้ Java ที่แนะนำให้คุณรู้จักในเวลานี้ หากคุณไม่เข้าใจอะไรคุณสามารถพูดคุยในพื้นที่ข้อความด้านล่าง ขอบคุณสำหรับการสนับสนุน Wulin.com