ในบทนี้เราจะแนะนำคำหลักที่ซิงโครไนซ์ เนื้อหาที่เกี่ยวข้องรวมถึง:
1. หลักการที่ซิงโครไนซ์
2. กฎพื้นฐานที่ซิงโครไนซ์
3. วิธีการซิงโครไนซ์และบล็อกรหัสที่ซิงโครไนซ์
4. ล็อคอินสแตนซ์และล็อคทั่วโลก
1. หลักการที่ซิงโครไนซ์
ใน Java แต่ละวัตถุมีและมีเพียงหนึ่งล็อคการซิงโครไนซ์ นอกจากนี้ยังหมายความว่าการล็อคการซิงโครไนซ์มีอยู่ในวัตถุ
เมื่อเราเรียกวิธีการซิงโครไนซ์ของวัตถุเราจะได้รับการล็อคการซิงโครไนซ์ของวัตถุ ตัวอย่างเช่นซิงโครไนซ์ (OBJ) ได้รับการล็อคการซิงโครไนซ์ของ "OBJ Object"
การเข้าถึงล็อคการซิงโครไนซ์โดยเธรดที่แตกต่างกันนั้นไม่เกิดร่วมกัน กล่าวอีกนัยหนึ่ง ณ เวลาหนึ่งเวลาล็อคการซิงโครไนซ์ของวัตถุสามารถรับได้โดยหนึ่งเธรด! ผ่านการล็อคการซิงโครไนซ์เราสามารถเข้าถึงการเข้าถึง "วัตถุ/วิธีการ" ซึ่งกันและกันร่วมกันในหลายเธรด ตัวอย่างเช่นขณะนี้มีสองเธรด A และ Thread B ซึ่งทั้งสองเข้าถึง "การล็อคแบบซิงโครนัสของ Object OBJ" สมมติว่าในบางจุดเธรด A ได้รับ "การเชื่อมโยงการซิงโครไนซ์ของ OBJ" และดำเนินการบางอย่าง B สามารถรับ "การล็อคการซิงโครไนซ์ของ OBJ" จนกว่าเธรด A จะปล่อย "การล็อคแบบซิงโครนัสของวัตถุนี้" และสามารถทำงานได้เท่านั้น
2. กฎพื้นฐานที่ซิงโครไนซ์
เราสรุปกฎพื้นฐานของการซิงโครไนซ์ลงใน 3 ต่อไปนี้และแสดงให้เห็นผ่านตัวอย่าง
บทความที่ 1: เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่นจะถูกบล็อกจากการเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุ"
บทความที่ 2: เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่น ๆ ยังสามารถเข้าถึงบล็อกรหัสแบบอะซิงโครไนซ์ของ "วัตถุนี้"
ข้อ 3: เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่น ๆ จะถูกบล็อกจากการเข้าถึง "วิธีการซิงโครไนซ์" อื่น ๆ หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุ"
ข้อ 1
เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่นจะถูกบล็อกจากการเข้าถึงไปยัง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุ"
ด้านล่างนี้เป็นโปรแกรมสาธิตที่สอดคล้องกับ "บล็อกรหัสที่ซิงโครไนซ์"
การคัดลอกรหัสมีดังนี้:
คลาส myrunable onplunable runnable {
@Override
โมฆะสาธารณะเรียกใช้ () {
ซิงโครไนซ์ (นี่) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "loop" + i);
-
} catch (interruptedException IE) {
-
-
-
-
ชั้นเรียนสาธารณะ demo1_1 {
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
Runnable Demo = new Myrunable ();
เธรด t1 = เธรดใหม่ (สาธิต "T1");
เธรด t2 = เธรดใหม่ (สาธิต "T2");
t1.start ();
t2.start ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T1 Loop 0
T1 Loop 1
T1 Loop 2
T1 Loop 3
T1 Loop 4
T2 Loop 0
T2 Loop 1
T2 Loop 2
T2 Loop 3
T2 Loop 4
ผลลัพธ์คำอธิบาย:
มี "บล็อกรหัสที่ซิงโครไนซ์ (นี้)" ในวิธีการเรียกใช้ () และ T1 และ T2 เป็นเธรดที่สร้างขึ้นตามวัตถุ "สาธิต" ซึ่งหมายความว่าเราสามารถพิจารณาสิ่งนี้ในการซิงโครไนซ์ (นี่) เป็น "วัตถุที่เรียกใช้งานได้" ดังนั้นเธรด T1 และ T2 แบ่งปัน "การล็อคแบบซิงโครนัสของวัตถุสาธิต" ดังนั้นเมื่อเธรดหนึ่งกำลังทำงานอยู่เธรดอื่นจะต้องรอ "เธรดที่รัน" เพื่อปล่อย "ล็อคการซิงโครไนซ์การสาธิต" ก่อนที่จะทำงาน
หากคุณยืนยันคุณจะพบปัญหานี้ จากนั้นเราแก้ไขรหัสด้านบนแล้วเรียกใช้เพื่อดูว่าผลลัพธ์เป็นอย่างไรและดูว่าคุณจะสับสนหรือไม่ ซอร์สโค้ดที่แก้ไขมีดังนี้:
การคัดลอกรหัสมีดังนี้:
คลาส MyThread ขยายเธรด {
Public Mythread (ชื่อสตริง) {
super (ชื่อ);
-
@Override
โมฆะสาธารณะเรียกใช้ () {
ซิงโครไนซ์ (นี่) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "loop" + i);
-
} catch (interruptedException IE) {
-
-
-
-
ชั้นเรียนสาธารณะ demo1_2 {
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
Thread T1 = ใหม่ MyThread ("T1");
Thread T2 = New MyThread ("T2");
t1.start ();
t2.start ();
-
-
รหัสคำอธิบาย:
เมื่อเปรียบเทียบ DEMO1_2 และ DEMO1_1 เราพบว่าคลาส MyThread ใน DEMO1_2 นั้นสืบทอดโดยตรงจากเธรดและ T1 และ T2 เป็นทั้งเธรดเด็กในตำนาน
โชคดีที่วิธี "Run () ของ DEMO1_2" เรียกอีกอย่างว่าซิงโครไนซ์ (นี่) เช่นเดียวกับวิธี "Run () ของ Demo1_1" หรือที่เรียกว่าซิงโครไนซ์ (นี่)!
ดังนั้นกระบวนการดำเนินการของ DEMO1_2 เหมือนกับ DEMO1_1 หรือไม่?
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T1 Loop 0
T2 Loop 0
T1 Loop 1
T2 Loop 1
T1 Loop 2
T2 Loop 2
T1 Loop 3
T2 Loop 3
T1 Loop 4
T2 Loop 4
ผลลัพธ์คำอธิบาย:
หากผลลัพธ์นี้ไม่ทำให้คุณประหลาดใจเลยฉันเชื่อว่าคุณมีความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับการซิงโครไนซ์และสิ่งนี้ มิฉะนั้นโปรดอ่านการวิเคราะห์ต่อไปที่นี่
สิ่งนี้อยู่ในการซิงโครไนซ์ (นี่) หมายถึง "วัตถุคลาสปัจจุบัน" นั่นคือวัตถุปัจจุบันที่สอดคล้องกับคลาสที่อยู่ในตำแหน่งที่ซิงโครไนซ์ (นี้) อยู่ วัตถุประสงค์คือเพื่อให้ได้ "ล็อคแบบซิงโครนัสของวัตถุปัจจุบัน"
สำหรับ DEMO1_2 สิ่งนี้อยู่ในการซิงโครไนซ์ (นี้) แสดงถึงวัตถุในขณะที่ T1 และ T2 เป็นวัตถุที่แตกต่างกันสองแบบ สำหรับคู่ Demo1_1 สิ่งนี้อยู่ในการซิงโครไนซ์ (นี้) แสดงถึงวัตถุ myrunable;
ข้อ 2
เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่น ๆ ยังสามารถเข้าถึงบล็อกรหัสแบบอะซิงโครไนซ์ของ "วัตถุนี้"
ด้านล่างนี้เป็นโปรแกรมสาธิตที่สอดคล้องกับ "บล็อกรหัสที่ซิงโครไนซ์"
การคัดลอกรหัสมีดังนี้:
นับคลาส {
// วิธีการที่มีบล็อกซิงโครไนซ์ซิงโครไนซ์
โมฆะสาธารณะ synmethod () {
ซิงโครไนซ์ (นี่) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "synmethod loop" + i);
-
} catch (interruptedException IE) {
-
-
-
// วิธีการแบบอะซิงโครนัส
โมฆะสาธารณะ nonsynmethod () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
Thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "nonsynmethod loop" + i);
-
} catch (interruptedException IE) {
-
-
-
ชั้นเรียนสาธารณะ demo2 {
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
นับจำนวนสุดท้าย = count ใหม่ ();
// สร้าง T1, T1 ใหม่จะเรียกวิธีการ synmethod () ของ "count object"
เธรด t1 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
count.synmethod ();
-
}, "t1");
// สร้างวิธี T2, T2 ใหม่จะเรียกวิธีการไม่ซินซิน () ของ "การนับวัตถุ"
เธรด t2 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
count.nonsynmethod ();
-
}, "t2");
t1.start ();
t2.start ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
t1 synmethod loop 0
t2 nonsynmethod loop 0
t1 synmethod loop 1
t2 nonsynmethod loop 1
T1 synmethod loop 2
t2 nonsynmethod loop 2
T1 synmethod loop 3
t2 nonsynmethod loop 3
T1 synmethod loop 4
t2 nonsynmethod loop 4
ผลลัพธ์คำอธิบาย:
สองเธรดเด็กใหม่ T1 และ T2 ถูกสร้างขึ้นในเธรดหลัก T1 จะเรียกวิธีการ synmethod () ของวัตถุการนับซึ่งมีบล็อกการซิงโครไนซ์; เมื่อ T1 กำลังทำงานอยู่แม้ว่าจะถูกเรียกเข้า (นี้) เพื่อให้ได้ "ล็อคการซิงโครไนซ์นับ";
ข้อ 3
เมื่อเธรดเข้าถึง "วิธีการซิงโครไนซ์" หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุบางอย่าง" เธรดอื่น ๆ จะเข้าถึง "วิธีการซิงโครไนซ์" อื่น ๆ หรือ "บล็อกรหัสที่ซิงโครไนซ์" ของ "วัตถุ" จะถูกบล็อก
นอกจากนี้เรายังจะปรับเปลี่ยนวิธีการที่ไม่ซิงซิง () ในตัวอย่างข้างต้นด้วยการซิงโครไนซ์ (นี้) ซอร์สโค้ดที่แก้ไขมีดังนี้:
การคัดลอกรหัสมีดังนี้:
นับคลาส {
// วิธีการที่มีบล็อกซิงโครไนซ์ซิงโครไนซ์
โมฆะสาธารณะ synmethod () {
ซิงโครไนซ์ (นี่) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "synmethod loop" + i);
-
} catch (interruptedException IE) {
-
-
-
// ยังมีวิธีการบล็อกซิงโครไนซ์ซิงโครไนซ์
โมฆะสาธารณะ nonsynmethod () {
ซิงโครไนซ์ (นี่) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
Thread.sleep (100);
System.out.println (thread.currentthread (). getName () + "nonsynmethod loop" + i);
-
} catch (interruptedException IE) {
-
-
-
-
ชั้นเรียนสาธารณะ demo3 {
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
นับจำนวนสุดท้าย = count ใหม่ ();
// สร้าง T1, T1 ใหม่จะเรียกวิธีการ synmethod () ของ "count object"
เธรด t1 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
count.synmethod ();
-
}, "t1");
// สร้างวิธี T2, T2 ใหม่จะเรียกวิธีการไม่ซินซิน () ของ "การนับวัตถุ"
เธรด t2 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
count.nonsynmethod ();
-
}, "t2");
t1.start ();
t2.start ();
-
-
(ครั้งเดียว) ผลการดำเนินการ:
การคัดลอกรหัสมีดังนี้:
synmethod (): 11
synblock (): 3
4. ล็อคอินสแตนซ์และล็อคทั่วโลก
อินสแตนซ์ล็อค-ล็อคบนวัตถุอินสแตนซ์ หากชั้นเรียนเป็นซิงเกิลตันแล้วล็อคก็มีแนวคิดของการล็อคทั่วโลก
คำหลักที่ซิงโครไนซ์สอดคล้องกับการล็อคอินสแตนซ์
Global Lock- ล็อคนี้มีเป้าหมายในชั้นเรียน
ล็อคทั่วโลกสอดคล้องกับการซิงโครไนซ์แบบคงที่ (หรือล็อคบนคลาสหรือวัตถุคลาสโหลดของคลาสนี้)
มีตัวอย่างที่ชัดเจนของ "ล็อคอินสแตนซ์" และ "ล็อคทั่วโลก":
การคัดลอกรหัสมีดังนี้:
คลาส Pulbic บางสิ่งบางอย่าง {
โมฆะที่ซิงโครไนซ์สาธารณะ Issynca () {}
โมฆะที่ซิงโครไนซ์สาธารณะ ISSYNCB () {}
โมฆะแบบสแตติกแบบคงที่สาธารณะ csynca () {}
void cyncb () {} เป็นโมฆะแบบคงที่
-
สมมติว่ามีบางอย่างมีสองอินสแตนซ์ x และ y วิเคราะห์ล็อคที่ได้รับโดยนิพจน์สี่ชุดต่อไปนี้
(01) X.ISSYNCA () และ X.ISSYNCB ()
(02) x.issynca () และ y.issynca ()
(03) x.csynca () และ y.csyncb ()
(04) x.issynca () และบางสิ่งบางอย่าง csynca ()
(01) ไม่สามารถเข้าถึงได้พร้อมกัน เพราะ ISSYNCA () และ ISSYNCB () เป็นล็อคการซิงโครไนซ์ที่เข้าถึงวัตถุเดียวกัน (วัตถุ X)!
การคัดลอกรหัสมีดังนี้:
// locktest2.java ซอร์ส
ชั้นเรียนบางสิ่งบางอย่าง {
Void Issynca () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issynca");
-
} catch (interruptedException IE) {
-
-
Void Issyncb () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issyncb");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csynca () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csynca");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csyncb () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csyncb");
-
} catch (interruptedException IE) {
-
-
-
คลาสสาธารณะ Locktest2 {
บางสิ่งบางอย่าง x = สิ่งใหม่ ();
บางสิ่งบางอย่าง y = สิ่งใหม่ ();
// เปรียบเทียบ (02) x.issynca () กับ y.issynca ()
โมฆะส่วนตัว test2 () {
// สร้าง T21 ใหม่และ T21 จะเรียก X.ISSYNCA ()
เธรด t21 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
X.ISSYNCA ();
-
}, "T21");
// สร้าง T22 ใหม่และ T22 จะเรียก X.ISSYNCB ()
เธรด t22 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
y.issynca ();
-
}, "T22");
t21.start ();
t22.start ();
-
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
DEMO LOCKTEST2 = ใหม่ LOCKTEST2 ();
demo.test2 ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T11: Issynca
T11: Issynca
T11: Issynca
T11: Issynca
T11: Issynca
T12: ISSYNCB
T12: ISSYNCB
T12: ISSYNCB
T12: ISSYNCB
T12: ISSYNCB
(02) สามารถเข้าถึงได้ในเวลาเดียวกัน เนื่องจากไม่ได้เข้าถึงการล็อคการซิงโครไนซ์ของวัตถุเดียวกัน x.issynca () เข้าถึงการล็อคการซิงโครไนซ์ของ x ในขณะที่ y.issynca () เข้าถึงล็อคการซิงโครไนซ์ของ y
การคัดลอกรหัสมีดังนี้:
// locktest2.java ซอร์ส
ชั้นเรียนบางสิ่งบางอย่าง {
Void Issynca () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issynca");
-
} catch (interruptedException IE) {
-
-
Void Issyncb () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issyncb");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csynca () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csynca");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csyncb () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csyncb");
-
} catch (interruptedException IE) {
-
-
-
คลาสสาธารณะ Locktest2 {
บางสิ่งบางอย่าง x = สิ่งใหม่ ();
บางสิ่งบางอย่าง y = สิ่งใหม่ ();
// เปรียบเทียบ (02) x.issynca () กับ y.issynca ()
โมฆะส่วนตัว test2 () {
// สร้าง T21 ใหม่และ T21 จะเรียก X.ISSYNCA ()
เธรด t21 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
X.ISSYNCA ();
-
}, "T21");
// สร้าง T22 ใหม่และ T22 จะเรียก X.ISSYNCB ()
เธรด t22 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
y.issynca ();
-
}, "T22");
t21.start ();
t22.start ();
-
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
DEMO LOCKTEST2 = ใหม่ LOCKTEST2 ();
demo.test2 ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T21: Issynca
T22: Issynca
T21: Issynca
T22: Issynca
T21: Issynca
T22: Issynca
T21: Issynca
T22: Issynca
T21: Issynca
T22: Issynca
(03) ไม่สามารถเข้าถึงได้พร้อมกัน เนื่องจาก csynca () และ csyncb () เป็นทั้งประเภทคงที่ x.csynca () เทียบเท่ากับบางสิ่งบางอย่าง issynca () และ y.csyncb () เทียบเท่ากับบางสิ่งบางอย่าง ถูกถามในเวลาเดียวกัน
การคัดลอกรหัสมีดังนี้:
// locktest3.java ซอร์ส
ชั้นเรียนบางสิ่งบางอย่าง {
Void Issynca () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issynca");
-
} catch (interruptedException IE) {
-
-
Void Issyncb () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issyncb");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csynca () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csynca");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csyncb () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csyncb");
-
} catch (interruptedException IE) {
-
-
-
คลาสสาธารณะ Locktest3 {
บางสิ่งบางอย่าง x = สิ่งใหม่ ();
บางสิ่งบางอย่าง y = สิ่งใหม่ ();
// เปรียบเทียบ (03) x.csynca () กับ y.csyncb ()
โมฆะส่วนตัว test3 () {
// สร้าง T31 ใหม่และ T31 จะเรียก X.ISSYNCA ()
เธรด t31 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
x.csynca ();
-
}, "T31");
// สร้าง T32 ใหม่และ T32 จะเรียก X.ISSYNCB ()
เธรด t32 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
y.csyncb ();
-
}, "t32");
t31.start ();
t32.start ();
-
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
DEMO LOCKTEST3 = ใหม่ LOCKTEST3 ();
demo.test3 ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T31: Csynca
T31: Csynca
T31: Csynca
T31: Csynca
T31: Csynca
T32: csyncb
T32: csyncb
T32: csyncb
T32: csyncb
T32: csyncb
(04) สามารถเข้าถึงได้พร้อมกัน เนื่องจาก ISSYNCA () เป็นวิธีการอินสแตนซ์, X.ISSYNCA () ใช้ล็อคของวัตถุ X; ดังนั้นพวกเขาสามารถเข้าถึงได้พร้อมกัน
การคัดลอกรหัสมีดังนี้:
// locktest4.java ซอร์ส
ชั้นเรียนบางสิ่งบางอย่าง {
Void Issynca () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issynca");
-
} catch (interruptedException IE) {
-
-
Void Issyncb () {) {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": issyncb");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csynca () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csynca");
-
} catch (interruptedException IE) {
-
-
โมฆะแบบสแตติกแบบคงที่สาธารณะ csyncb () {
พยายาม {
สำหรับ (int i = 0; i <5; i ++) {
thread.sleep (100);
System.out.println (thread.currentthread (). getName ()+": csyncb");
-
} catch (interruptedException IE) {
-
-
-
คลาสสาธารณะ Locktest4 {
บางสิ่งบางอย่าง x = สิ่งใหม่ ();
บางสิ่งบางอย่าง y = สิ่งใหม่ ();
// เปรียบเทียบ (04) x.issynca () กับบางสิ่งบางอย่าง csynca ()
โมฆะส่วนตัว test4 () {
// สร้าง T41 ใหม่และ T41 จะเรียก X.ISSYNCA ()
เธรด t41 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
X.ISSYNCA ();
-
}, "T41");
// สร้าง T42 ใหม่และ T42 จะเรียก X.ISSYNCB ()
เธรด t42 = เธรดใหม่ (
ใหม่ runnable () {
@Override
โมฆะสาธารณะเรียกใช้ () {
บางสิ่งบางอย่าง csynca ();
-
}, "t42");
t41.start ();
t42.start ();
-
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {
DEMO LOCKTEST4 = ใหม่ LOCKTEST4 ();
demo.test4 ();
-
-
ผลการทำงาน:
การคัดลอกรหัสมีดังนี้:
T41: Issynca
T42: Csynca
T41: Issynca
T42: Csynca
T41: Issynca
T42: Csynca
T41: Issynca
T42: Csynca
T41: Issynca
T42: Csynca