รหัสต่อไปนี้สาธิตวิธีการซิงโครไนซ์วิธีการเรียนเฉพาะ:
คัดลอกรหัสรหัสดังต่อไปนี้:
ตำนานแพ็คเกจ;
SyncThread คลาสสาธารณะขยายเธรด
-
การซิงค์สตริงคงที่ส่วนตัว = "";
methodType สตริงส่วนตัว = "";
วิธีการโมฆะคงที่ส่วนตัว (สตริง s)
-
ซิงโครไนซ์ (ซิงค์)
-
ซิงค์ = s;
System.out.println(s);
ในขณะที่ (จริง);
-
-
โมฆะสาธารณะ method1 ()
-
วิธีการ("วิธีที่1");
-
โมฆะคงที่สาธารณะ staticMethod1()
-
วิธีการ("staticMethod1");
-
การรันโมฆะสาธารณะ ()
-
ถ้า (methodType.equals("static"))
staticMethod1();
อย่างอื่นถ้า (methodType.equals("ไม่คงที่"))
วิธีที่ 1();
-
SyncThread สาธารณะ (String methodType)
-
this.methodType = methodType;
-
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น
-
SyncThread Sample1 = ใหม่ SyncThread("ไม่คงที่");
SyncThread Sample2 = ใหม่ SyncThread("static");
ตัวอย่าง1.เริ่มต้น();
ตัวอย่าง2.เริ่มต้น();
-
-
ผลการวิ่งมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
วิธีที่ 1
วิธีคงที่1
ผู้อ่านหลายคนอาจแปลกใจเมื่อเห็นผลการดำเนินการข้างต้น ในโค้ดด้านบน วิธี method1 และ staticMethod1 ใช้การซิงค์ตัวแปรสตริงแบบคงที่สำหรับการซิงโครไนซ์ สามารถดำเนินการได้เพียงวิธีใดวิธีหนึ่งจากสองวิธีนี้ในเวลาเดียวกัน และทั้งสองวิธีจะดำเนินการคำสั่ง infinite loop ในบรรทัด 014 ดังนั้นผลลัพธ์เอาต์พุตจึงเป็นได้เพียงวิธีใดวิธีหนึ่งและ staticMethod1 เท่านั้น แต่โปรแกรมนี้ส่งออกทั้งสองสาย
เหตุผลของผลลัพธ์นี้ง่ายมาก เราจะรู้ได้จากบรรทัดที่ 012 ปรากฎว่าค่าการซิงค์มีการเปลี่ยนแปลงในบรรทัดนี้ ที่นี่ฉันต้องการพูดคุยเกี่ยวกับประเภท String ใน Java ประเภท String แตกต่างจากประเภทที่ซับซ้อนอื่นๆ ใน Java เมื่อใช้ตัวแปรประเภทสตริง ตราบใดที่คุณกำหนดค่าให้กับตัวแปรเพียงครั้งเดียว Java จะสร้างอินสแตนซ์ใหม่ของประเภทสตริง ดังแสดงในรหัสต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
สตริง s = "สวัสดี";
System.out.println(s.hashCode());
s = "โลก";
System.out.println(s.hashCode());
ในโค้ดด้านบน ค่า hashCode ของ s แรกและ s ที่กำหนดใหม่นั้นแตกต่างกัน เนื่องจากการสร้างอินสแตนซ์ของคลาส String ไม่จำเป็นต้องใช้ new เมื่อทำการซิงโครไนซ์ตัวแปรประเภท String โปรดระวังอย่ากำหนดค่าให้กับตัวแปรนี้ ไม่เช่นนั้นตัวแปรจะไม่ถูกซิงโครไนซ์
เนื่องจากมีการสร้างอินสแตนซ์ใหม่สำหรับการซิงค์ในบรรทัด 012 สมมติว่าวิธีที่ 1 ถูกดำเนินการก่อน เมื่อวิธีที่ 1 เรียกใช้โค้ดในบรรทัด 013 ค่าของการซิงค์จะไม่เป็นค่าเดิมอีกต่อไป และวิธีที่ 1 ยังคงล็อกตัวแปรการซิงค์เป็นค่าเริ่มต้น . ในขณะนี้ staticMethod1 เกิดขึ้นเพื่อดำเนินการซิงโครไนซ์ (ซิงค์) การซิงค์ที่จะล็อคในวิธี staticMethod1 และการซิงค์ที่ถูกล็อคโดยวิธี method1 จะไม่เหมือนกันอีกต่อไป ดังนั้น การซิงโครไนซ์ของทั้งสองวิธีจึงถูกทำลาย
วิธีแก้ปัญหาข้างต้นคือการลบบรรทัด 012 ออก บรรทัดนี้ถูกเพิ่มในตัวอย่างนี้เพียงเพื่อแสดงให้เห็นว่าเมื่อใช้ตัวแปรคลาสเพื่อซิงโครไนซ์วิธีการ ถ้าค่าของตัวแปรการซิงโครไนซ์มีการเปลี่ยนแปลงในบล็อกที่ซิงโครไนซ์ การซิงโครไนซ์ระหว่างวิธีการจะถูกทำลาย เพื่อหลีกเลี่ยงสถานการณ์นี้โดยสิ้นเชิง คุณสามารถใช้คีย์เวิร์ดสุดท้ายเมื่อกำหนดตัวแปรการซิงโครไนซ์ ตัวอย่างเช่น บรรทัด 005 ในโปรแกรมด้านบนสามารถเปลี่ยนเป็นรูปแบบต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
การซิงค์สตริงคงที่ขั้นสุดท้ายส่วนตัว = "";
หลังจากใช้คีย์เวิร์ดสุดท้ายแล้ว การซิงค์สามารถกำหนดค่าให้กับคีย์เวิร์ดได้เมื่อมีการกำหนดเท่านั้น และไม่สามารถแก้ไขได้ในภายหลัง หากมีการกำหนดค่าการซิงค์ไว้ที่อื่นในโปรแกรม โปรแกรมจะไม่คอมไพล์ ในเครื่องมือการพัฒนาเช่น Eclipse จะมีการแจ้งพร้อมท์โดยตรงในตำแหน่งที่ไม่ถูกต้อง
เราสามารถเข้าใจบล็อกที่ซิงโครไนซ์ได้จากสองมุมมอง หากเข้าใจจากมุมมองของวิธีการเรียน วิธีการที่สอดคล้องกันสามารถซิงโครไนซ์ผ่านตัวแปรคลาส หากคุณเข้าใจจากมุมมองของตัวแปรคลาส คุณสามารถใช้บล็อกที่ซิงโครไนซ์เพื่อให้แน่ใจว่าตัวแปรคลาสสามารถเข้าถึงได้ด้วยวิธีเดียวเท่านั้นในเวลาเดียวกัน ไม่ว่าคุณจะเข้าใจจากมุมไหน สาระสำคัญของพวกมันก็เหมือนกัน นั่นคือการใช้ตัวแปรคลาสเพื่อรับล็อคการซิงโครไนซ์ และบรรลุการซิงโครไนซ์ผ่านการยกเว้นร่วมกันของการล็อคการซิงโครไนซ์
หมายเหตุ: เมื่อใช้บล็อกที่ซิงโครไนซ์ คุณควรทราบว่าบล็อกที่ซิงโครไนซ์สามารถใช้ได้เฉพาะออบเจ็กต์เป็นพารามิเตอร์เท่านั้น หากเป็นตัวแปรชนิดธรรมดา (เช่น int, char, boolean ฯลฯ) การซิงโครไนซ์จะไม่สามารถนำมาใช้สำหรับการซิงโครไนซ์ได้