Lockksupport เป็นด้ายพื้นฐานบล็อกดั้งเดิมที่ใช้ในการสร้างล็อคและคลาสการซิงโครไนซ์อื่น ๆ
ฟังก์ชั่นของ Park () และ unpark () ใน locksupport คือการบล็อกเธรดและปลดล็อคเธรดตามลำดับและ park () และ unpark () จะไม่พบ "deadlocks ที่อาจเกิดจาก Thread.suspend และ Thread.resume"
เพราะ Park () และ unpark () มีสิทธิ์; การแข่งขันระหว่าง Thread Calling Park () และเธรดอื่นที่พยายามทำผิดพลาด () จะยังคงทำงานอยู่
การใช้งานขั้นพื้นฐาน
Locksupport นั้นคล้ายกับสัญญาณไบนารี (มีเพียง 1 ใบอนุญาตเท่านั้น) หากใบอนุญาตนี้ยังไม่ได้ครอบครองเธรดปัจจุบันจะได้รับใบอนุญาตและดำเนินการต่อไป หากใบอนุญาตถูกครอบครองบล็อกเธรดปัจจุบันรอรับใบอนุญาต
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {locksupport.park (); System.out.println ("block.");}การเรียกใช้รหัสจะเปิดเผยว่าเธรดหลักจะปิดกั้นเสมอ เนื่องจากใบอนุญาตถูกครอบครองโดยค่าเริ่มต้นใบอนุญาตจึงไม่สามารถรับได้เมื่อโทร () ดังนั้นจึงเข้าสู่สถานะการปิดกั้น
รหัสต่อไปนี้: ปล่อยใบอนุญาตก่อนจากนั้นรับใบอนุญาตและเธรดหลักสามารถยกเลิกได้ตามปกติ การได้มาและการเปิดตัวของใบอนุญาต Locksupport นั้นสอดคล้องกันโดยทั่วไป หากคุณเลิกทำหลายครั้งจะไม่มีปัญหาถ้าคุณจอดครั้งเดียวเท่านั้น เป็นผลให้ใบอนุญาตอยู่ในสถานะที่มีอยู่
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {เธรดเธรด = เธรด currentthread (); lockksupport.unpark (เธรด); // ปล่อยใบอนุญาต linister locksupport.park (); // รับ system.out.out.println ("b");}Locksupport ไม่ได้กลับมาอีกครั้ง หากเธรดเรียก locksupport .park () สองครั้งในแถวแล้วเธรดจะบล็อกแน่นอน
โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่นข้อยกเว้น {เธรดเธรด = เธรด currentthread (); locksupport.unpark (เธรด); System.out.println ("A"); lockksupport.park (); System.out.println ("B"); lockksupport.park (); System.out.println ("C");}รหัสนี้พิมพ์ A และ B แต่ไม่ได้พิมพ์ C เนื่องจากเธรดไม่สามารถได้รับอนุญาตเมื่อโทรไปที่ Park เป็นครั้งที่สอง
ลองมาดูการตอบสนองของการขัดจังหวะที่สอดคล้องกันของ Lockksupport
โมฆะคงที่สาธารณะ t2 () พ่นข้อยกเว้น {เธรด t = เธรดใหม่ (ใหม่ runnable () {count int ส่วนตัว = 0; @Override โมฆะสาธารณะเรียกใช้ () {long start = system.currentTimeMillis (); Long end = 0; (end - start) <= 1000) {count ++; second.count = " + count); // รอการอนุญาตให้ได้รับอนุญาต locksupport.park (); system.out.println (" เธรดมากกว่า " + thread.currentthread (). isInterrupted ());}}); T.Start (); Thread.sleep (2000); // อินเตอร์รัปต์เธรด t.interrupt (); System.out.println ("Main Over");}เธรดจะพิมพ์เธรด over.true ซึ่งหมายความว่าหากบล็อกเธรดเนื่องจากการเรียกพาร์คมันสามารถตอบสนองต่อคำขอขัดจังหวะ (สถานะการขัดจังหวะถูกตั้งค่าเป็นจริง) แต่จะไม่โยนการขัดจังหวะ
รายการฟังก์ชั่น locksupport
// ส่งคืนวัตถุบล็อกเกอร์ที่มีให้ไปยังการโทรที่ไม่ถูกบล็อกล่าสุดและส่งคืนค่า null หากการโทรไม่ถูกบล็อก วัตถุคงที่ getBlocker (เธรด t) // สำหรับการตั้งเวลาเธรดให้ปิดการใช้งานเธรดปัจจุบันเว้นแต่จะมีสิทธิ์ใช้งาน Static Void Park () // สำหรับการตั้งเวลาเธรดให้ปิดการใช้งานเธรดปัจจุบันก่อนที่จะมีใบอนุญาต พาร์ค Void Static (Object Blocker) // สำหรับการตั้งเวลาเธรดรอเวลารอคอยที่กำหนดมากที่สุดเว้นแต่จะมีใบอนุญาต Void Parknanos แบบคงที่ (Long Nanos) // สำหรับการตั้งเวลาเธรดให้ปิดการใช้งานเธรดปัจจุบันก่อนที่จะมีใบอนุญาตและรอเวลารอคอยที่กำหนดมากที่สุด parknanos void void (blocker object, long nanos) // สำหรับการตั้งเวลาเธรดเธรดปัจจุบันจะถูกปิดใช้งานก่อนที่จะ จำกัด เวลาที่กำหนดเว้นแต่จะมีใบอนุญาต Void Parkuntil แบบคงที่ (กำหนดเวลายาว) // สำหรับการตั้งเวลาเธรดเธรดปัจจุบันจะถูกปิดใช้งานก่อนที่จะ จำกัด เวลาที่กำหนดเว้นแต่จะมีใบอนุญาต Void Parkuntil แบบคงที่ (Object Blocker, Long Dentline) // ทำให้สามารถใช้งานได้หากใบอนุญาตของเธรดที่กำหนดยังไม่สามารถใช้ได้ โมฆะคงที่ unpark (เธรดด้าย)
ตัวอย่าง locksupport
การเปรียบเทียบ "ตัวอย่าง 1" และ "ตัวอย่างที่ 2" ด้านล่างสามารถให้ความเข้าใจที่ชัดเจนยิ่งขึ้นเกี่ยวกับการใช้งานของ Locksupport
ตัวอย่างที่ 1
คลาสสาธารณะ waittest1 {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada ta = new Threada ("ta"); ซิงโครไนซ์ (ta) {// รับ "การล็อคการซิงโครไนซ์ของวัตถุ ta" ผ่านการซิงโครไนซ์ (ta) ลอง {system.out.println (thread.currentthread (). getName ()+"start ta"); ta.start (); System.out.println (thread.currentthread (). getName ()+"block"); // เธรดหลักกำลังรอ ta.wait (); System.out.println (thread.currentthread (). getName ()+"ดำเนินการต่อ"); } catch (interruptedException e) {e.printStackTrace (); }}} คลาสคงที่เธรดขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } public void run () {ซิงโครไนซ์ (นี่) {// get "การล็อคการซิงโครไนซ์ของวัตถุปัจจุบัน" ผ่านซิงโครไนซ์ (นี้) system.out.println (thread.currentthread (). getName ()+"wakup อื่น ๆ "); แจ้ง(); // Wake Up "รอเธรดบนวัตถุปัจจุบัน"}}}} ตัวอย่างที่ 2
นำเข้า java.util.concurrent.locks.locksupport; LocksupportTest1 ระดับสาธารณะ {เธรดแบบคงที่ส่วนตัว MainThread; โมฆะคงที่สาธารณะหลัก (สตริง [] args) {threada ta = threada ใหม่ ("ta"); // รับเธรดหลัก mainThread = tread.currentthread (); System.out.println (thread.currentthread (). getName ()+"เริ่ม ta"); ta.start (); System.out.println (thread.currentthread (). getName ()+"block"); // บล็อกหลักบล็อก locksupport.park (mainthread); System.out.println (thread.currentthread (). getName ()+"ดำเนินการต่อ"); } ชั้นเรียนแบบคงที่ threada ขยายเธรด {public threada (ชื่อสตริง) {super (ชื่อ); } โมฆะสาธารณะเรียกใช้ () {system.out.println (thread.currentthread (). getName ()+"wakup อื่น ๆ "); // ปลุก "เธรดหลัก" locksupport.unpark (mainthread); - ผลการทำงาน:
หลักเริ่มต้น Tamain Blockta Wakup อื่น ๆ
คำอธิบาย: ความแตกต่างระหว่างสวนสาธารณะและรอ ก่อนที่จะรอเธรดบล็อกจะต้องได้รับการล็อคการซิงโครไนซ์ผ่านการซิงโครไนซ์