ในฐานะเครื่องมือสำหรับการแบ่งปันข้อมูลพร้อมกันและรับประกันความสอดคล้อง การล็อคมีการใช้งานหลายอย่างบนแพลตฟอร์ม JAVA (เช่น การซิงโครไนซ์และ ReentrantLock เป็นต้น) ล็อคที่เขียนไว้แล้วเหล่านี้ให้ความสะดวกในการพัฒนาของเรา แต่ไม่ค่อยมีการกล่าวถึงลักษณะเฉพาะและประเภทของล็อค บทความชุดนี้จะวิเคราะห์ชื่อล็อคทั่วไปและคุณลักษณะภายใต้ JAVA เพื่อตอบคำถามของคุณ
4. ล็อคการกลับเข้าใหม่:
บทความนี้พูดถึงการล็อกผู้เข้าใหม่ในแง่กว้าง ไม่ใช่แค่ ReentrantLock ภายใต้ JAVA
Reentrant locks หรือที่เรียกว่า recursive locks หมายความว่าหลังจากที่ฟังก์ชันภายนอกของ thread เดียวกันได้รับการล็อคแล้ว ฟังก์ชัน recursive ภายในยังคงมีโค้ดเพื่อรับการล็อค แต่จะไม่ได้รับผลกระทบ
ในสภาพแวดล้อม JAVA ReentrantLock และการซิงโครไนซ์เป็นทั้งการล็อกการกลับเข้าใหม่
นี่คือตัวอย่างการใช้งาน:
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบคลาสสาธารณะใช้ Runnable {
โมฆะการซิงโครไนซ์สาธารณะรับ () {
System.out.println(Thread.currentThread().getId());
ชุด();
-
ชุดโมฆะซิงโครไนซ์สาธารณะ () {
System.out.println(Thread.currentThread().getId());
-
@แทนที่
โมฆะสาธารณะวิ่ง () {
รับ();
-
โมฆะคงที่สาธารณะ main (String [] args) {
ทดสอบ ss=การทดสอบใหม่();
เธรดใหม่(ss).start();
เธรดใหม่(ss).start();
เธรดใหม่(ss).start();
-
-
ผลลัพธ์สุดท้ายของทั้งสองตัวอย่างนั้นถูกต้อง นั่นคือ thread ID เดียวกันจะถูกส่งออกสองครั้งติดต่อกัน
ผลลัพธ์จะเป็นดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
เธรด: 8
เธรด: 8
รหัสเธรด: 10
รหัสเธรด: 10
เธรด: 9
เธรด: 9
บทบาทที่ใหญ่ที่สุดของการล็อคผู้กลับเข้ามาใหม่คือการหลีกเลี่ยงการหยุดชะงัก
ลองใช้สปินล็อคเป็นตัวอย่าง
คัดลอกรหัสรหัสดังต่อไปนี้:
SpinLock คลาสสาธารณะ {
เจ้าของ AtomicReference <Thread> ส่วนตัว = AtomicReference ใหม่ <> ();
โมฆะสาธารณะล็อค () {
เธรดปัจจุบัน = Thread.currentThread();
ในขณะที่(!owner.compareAndSet(null, ปัจจุบัน)){
-
-
การปลดล็อคโมฆะสาธารณะ (){
เธรดปัจจุบัน = Thread.currentThread();
Owner.compareAndSet (ปัจจุบัน, null);
-
-
สำหรับตัวล็อคแบบหมุน:
1. หากเธรดเดียวกันเรียก lock() สองครั้ง จะทำให้ตำแหน่งล็อคถูกเรียกเป็นครั้งที่สอง หากเกิดการชะงักงัน หมายความว่าการล็อคไม่ได้กลับเข้ามาใหม่ (ในฟังก์ชั่นล็อคคุณควรตรวจสอบว่าด้ายเป็นด้ายที่ได้รับการล็อคหรือไม่)
2. หากปัญหาที่ 1 ได้รับการแก้ไขแล้ว การล็อคจะถูกปลดล็อคเมื่อมีการเรียกการปลดล็อค () เป็นครั้งแรก ไม่ควรปลดล็อคจริงๆ
(ใช้การนับครั้งเป็นสถิติ)
หลังจากแก้ไขแล้วจะเป็นดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
SpinLock1 คลาสสาธารณะ {
เจ้าของ AtomicReference <Thread> ส่วนตัว = AtomicReference ใหม่ <> ();
จำนวน int ส่วนตัว = 0;
โมฆะสาธารณะล็อค () {
เธรดปัจจุบัน = Thread.currentThread();
ถ้า (ปัจจุบัน==owner.get()) {
นับ++;
กลับ ;
-
ในขณะที่(!owner.compareAndSet(null, ปัจจุบัน)){
-
-
การปลดล็อคโมฆะสาธารณะ (){
เธรดปัจจุบัน = Thread.currentThread();
ถ้า(ปัจจุบัน==owner.get()){
ถ้า(นับ!=0){
นับ--;
}อื่น{
Owner.compareAndSet (ปัจจุบัน, null);
-
-
-
-
ล็อคแบบหมุนนี้เป็นล็อคกลับเข้าใหม่