คัดลอกรหัสรหัสดังต่อไปนี้:
การรันโมฆะแบบซิงโครไนซ์สาธารณะ ()
-
-
ดังที่เห็นได้จากโค้ดข้างต้น ตราบใดที่คีย์เวิร์ดที่ซิงโครไนซ์ถูกเพิ่มระหว่าง void และ public วิธีการ run ก็สามารถซิงโครไนซ์ได้ กล่าวคือ สำหรับอินสแตนซ์อ็อบเจ็กต์ของคลาส Java เดียวกัน วิธีการ run สามารถทำได้เท่านั้น เรียกโดยเธรดเดียวในเวลาเดียวกัน และสามารถเรียกโดยเธรดอื่นได้หลังจากดำเนินการรันปัจจุบันแล้วเท่านั้น แม้ว่าเธรดปัจจุบันจะเรียกใช้งานวิธี Yield ในวิธี run แต่จะหยุดชั่วคราวเพียงชั่วขณะหนึ่งเท่านั้น เนื่องจากเธรดอื่นไม่สามารถดำเนินการตามวิธีการเรียกใช้ได้ เธรดปัจจุบันจะดำเนินการดำเนินการต่อไปในที่สุด ลองดูโค้ดต่อไปนี้ก่อน:
คำสำคัญที่ซิงโครไนซ์ถูกผูกไว้กับอินสแตนซ์ออบเจ็กต์เดียวเท่านั้น
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบในชั้นเรียน
-
วิธีการโมฆะซิงโครไนซ์สาธารณะ ()
-
-
-
การซิงค์คลาสสาธารณะใช้ Runnable
-
การทดสอบการทดสอบส่วนตัว
การรันโมฆะสาธารณะ ()
-
ทดสอบวิธีการ();
-
ซิงค์สาธารณะ (ทดสอบทดสอบ)
-
this.test = ทดสอบ;
-
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น
-
ทดสอบ test1 = ทดสอบใหม่ ();
ทดสอบ test2 = ทดสอบใหม่ ();
ซิงค์ sync1 = ซิงค์ใหม่ (test1);
ซิงค์ sync2 = ซิงค์ใหม่ (test2);
เธรดใหม่ (sync1).start();
เธรดใหม่ (sync2).start();
-
-
วิธีการวิธีการในคลาสการทดสอบเป็นแบบซิงโครนัส แต่โค้ดด้านบนจะสร้างคลาส Test สองอินสแตนซ์ ดังนั้นเมธอดของ test1 และ test2 จะถูกดำเนินการแยกกัน ในการซิงโครไนซ์เมธอด คุณต้องส่งอินสแตนซ์ของคลาส Test เดียวกันไปยัง Constructor เมื่อสร้างอินสแตนซ์ของคลาส Sync ดังที่แสดงในโค้ดต่อไปนี้:
ซิงค์ sync1 = ซิงค์ใหม่ (test1);
ไม่เพียงแต่คุณสามารถใช้การซิงโครไนซ์เพื่อซิงโครไนซ์วิธีการที่ไม่คงที่เท่านั้น คุณยังสามารถใช้การซิงโครไนซ์เพื่อซิงโครไนซ์วิธีการคงที่ได้อีกด้วย ตัวอย่างเช่น วิธีการ วิธีการสามารถกำหนดได้ดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบในชั้นเรียน
-
วิธีการโมฆะแบบซิงโครไนซ์สาธารณะแบบคงที่ () { }
-
สร้างอินสแตนซ์วัตถุของคลาสทดสอบดังนี้:
ทดสอบ ทดสอบ = ทดสอบใหม่();
สำหรับวิธีการแบบสแตติก ตราบใดที่มีการเพิ่มคำสำคัญที่ซิงโครไนซ์ วิธีการนั้นก็จะถูกซิงโครไนซ์ ไม่ว่าคุณจะใช้ test.method() หรือ Test.method() เพื่อเรียกเมธอดเมธอด วิธีการนั้นก็จะซิงโครไนซ์และไม่มีปัญหากับหลาย ๆ วิธี ตัวอย่างของวิธีการที่ไม่คงที่
ในบรรดารูปแบบการออกแบบ 23 รูปแบบ โหมดซิงเกิลตันนั้นไม่ปลอดภัยสำหรับเธรดหากออกแบบตามวิธีการดั้งเดิม รหัสต่อไปนี้คือโหมดซิงเกิลตันที่ไม่ปลอดภัยสำหรับเธรด
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบบรรจุภัณฑ์
// โหมดซิงเกิลตันแบบปลอดภัยสำหรับเธรด
คลาสซิงเกิลตัน
-
ตัวอย่างซิงเกิลตันแบบคงที่ส่วนตัว
ซิงเกิลตันส่วนตัว ()
-
-
สาธารณะคงที่ Singleton getInstance ()
-
ถ้า (ตัวอย่าง == null)
-
Thread.yield(); // เพื่อขยายความไม่มั่นคงของเธรดของโหมดซิงเกิลตัน
ตัวอย่าง = ซิงเกิลตันใหม่ ();
-
ส่งตัวอย่างกลับ;
-
-
MyThread คลาสสาธารณะขยายเธรด
-
การรันโมฆะสาธารณะ ()
-
ซิงเกิลตัน ซิงเกิลตัน = Singleton.getInstance();
System.out.println(singleton.hashCode());
-
โมฆะสาธารณะคง main (String [] args)
-
เธรดเธรด[] = เธรดใหม่[5];
สำหรับ (int i = 0; i < threads.length; i++)
เธรด [i] = MyThread ใหม่ ();
สำหรับ (int i = 0; i < threads.length; i++)
กระทู้[i].เริ่มต้น();
-
-
วิธีการ Yield ถูกเรียกในโค้ดด้านบนเพื่อทำให้เธรดที่ไม่ปลอดภัยของโหมดซิงเกิลตันปรากฏขึ้น หากบรรทัดนี้ถูกลบ การใช้งานข้างต้นจะยังคงไม่ปลอดภัยสำหรับเธรด แต่ความเป็นไปได้ที่จะเกิดขึ้นจะน้อยกว่ามาก
ผลลัพธ์การรันโปรแกรมมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
25358555
26399554
7051261
29855319
5383406
ผลลัพธ์การรันข้างต้นอาจแตกต่างกันในสภาพแวดล้อมการทำงานที่แตกต่างกัน แต่โดยทั่วไปเอาต์พุตทั้งห้าบรรทัดจะไม่เหมือนกันทุกประการ ดังที่เห็นได้จากเอาต์พุตนี้ มีอินสแตนซ์อ็อบเจ็กต์ห้าอินสแตนซ์ที่ได้รับผ่านเมธอด getInstance ไม่ใช่หนึ่งรายการอย่างที่เราคาดไว้ เนื่องจากเมื่อเธรดดำเนินการ Thread.yield() เธรดนั้นจะมอบทรัพยากร CPU ให้กับเธรดอื่น เนื่องจากคำสั่งในการสร้างอินสแตนซ์ออบเจ็กต์เดี่ยวไม่ได้ถูกดำเนินการเมื่อสลับระหว่างเธรด เธรดเหล่านี้ทั้งหมดผ่านการตัดสิน if ดังนั้น อินสแตนซ์ออบเจ็กต์ห้ารายการจะถูกสร้างขึ้น (สี่รายการอาจถูกสร้างขึ้น) หรือสามอินสแตนซ์ของออบเจ็กต์ ขึ้นอยู่กับจำนวนเธรดที่ผ่าน หากพิจารณาก่อนสร้างออบเจ็กต์ Singleton ผลลัพธ์อาจแตกต่างกันในแต่ละครั้งที่มีการรัน)
หากต้องการทำให้เธรดโหมดซิงเกิลตันข้างต้นปลอดภัย เพียงเพิ่มคีย์เวิร์ดที่ซิงโครไนซ์ลงใน getInstance รหัสมีดังนี้:
สาธารณะแบบซิงโครไนซ์ Singleton getInstance () { }
แน่นอนว่ามีวิธีที่ง่ายกว่าคือการสร้างวัตถุ Singleton เมื่อกำหนดตัวแปร Singleton รหัสจะเป็นดังนี้:
ตัวอย่าง Singleton สุดท้ายแบบคงที่ส่วนตัว = new Singleton ();
จากนั้นเพียงส่งคืนตัวอย่างโดยตรงในเมธอด getInstance แม้ว่าวิธีนี้จะง่าย แต่ก็ไม่ยืดหยุ่นในการสร้างออบเจ็กต์ Singleton ในเมธอด getInstance ผู้อ่านสามารถเลือกใช้วิธีการต่างๆ เพื่อใช้รูปแบบซิงเกิลตันได้ตามความต้องการเฉพาะ
มีสี่ประเด็นที่ควรทราบเมื่อใช้คำสำคัญที่ซิงโครไนซ์:
1. คำสำคัญที่ซิงโครไนซ์ไม่สามารถสืบทอดได้
แม้ว่าคุณสามารถใช้การซิงโครไนซ์เพื่อกำหนดวิธีการได้ แต่การซิงโครไนซ์ไม่ได้เป็นส่วนหนึ่งของคำจำกัดความของวิธีการ ดังนั้นคำสำคัญที่ซิงโครไนซ์จึงไม่สามารถสืบทอดได้ ถ้าเมธอดในคลาสพาเรนต์ใช้คีย์เวิร์ดที่ซิงโครไนซ์และแทนที่เมธอดนี้ในคลาสย่อย วิธีการในคลาสย่อยจะไม่ซิงโครไนซ์ตามค่าเริ่มต้น และจะต้องระบุอย่างชัดเจนในคลาสย่อย เพียงเพิ่มคีย์เวิร์ดที่ซิงโครไนซ์เข้ากับเมธอด แน่นอน คุณยังสามารถเรียกวิธีการที่สอดคล้องกันในคลาสหลักในวิธีการคลาสย่อยได้ ด้วยวิธีนี้ แม้ว่าวิธีการในคลาสย่อยจะไม่ซิงโครไนซ์ แต่คลาสย่อยจะเรียกวิธีการซิงโครไนซ์ของคลาสพาเรนต์ คลาสย่อยเทียบเท่ากับการซิงโครไนซ์ รหัสตัวอย่างสำหรับทั้งสองวิธีนี้มีดังนี้:
เพิ่มคีย์เวิร์ดที่ซิงโครไนซ์เข้ากับเมธอดคลาสย่อย
คัดลอกรหัสรหัสดังต่อไปนี้:
ผู้ปกครองชั้นเรียน
-
วิธีการโมฆะซิงโครไนซ์สาธารณะ () { }
-
คลาส Child ขยายผู้ปกครอง
-
วิธีการโมฆะซิงโครไนซ์สาธารณะ () { }
-
เรียกวิธีการซิงโครไนซ์ของคลาสแม่ในวิธีการคลาสย่อย
คัดลอกรหัสรหัสดังต่อไปนี้:
ผู้ปกครองชั้นเรียน
-
วิธีการโมฆะซิงโครไนซ์สาธารณะ () { }
-
คลาส Child ขยายผู้ปกครอง
-
วิธีการเป็นโมฆะสาธารณะ () { super.method ();
-
2. ไม่สามารถใช้คำสำคัญที่ซิงโครไนซ์เมื่อกำหนดวิธีอินเทอร์เฟซ
3. ตัวสร้างไม่สามารถใช้คำสำคัญที่ซิงโครไนซ์ได้ แต่สามารถใช้บล็อกที่ซิงโครไนซ์เพื่อหารือในส่วนถัดไปสำหรับการซิงโครไนซ์
4. สามารถซิงโครไนซ์ได้อย่างอิสระ
ในตัวอย่างก่อนหน้านี้ คำสำคัญที่ซิงโครไนซ์จะถูกวางไว้ด้านหน้าประเภทการส่งคืนของวิธีการ แต่นี่ไม่ใช่สถานที่เดียวที่สามารถซิงโครไนซ์ได้ ในวิธีการที่ไม่คงที่ การซิงโครไนซ์สามารถวางไว้ด้านหน้าคำจำกัดความของวิธีการได้ ในวิธีการแบบคงที่ การซิงโครไนซ์สามารถวางไว้ด้านหน้าแบบคงที่ได้ รหัสจะเป็นดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
วิธีการโมฆะซิงโครไนซ์สาธารณะ ();
วิธีการโมฆะสาธารณะที่ซิงโครไนซ์ ();
วิธีการโมฆะแบบซิงโครไนซ์สาธารณะแบบคงที่ ();
วิธีการโมฆะคงที่สาธารณะซิงโครไนซ์ ();
การซิงโครไนซ์วิธีการโมฆะสาธารณะแบบคงที่ ();
แต่โปรดทราบว่าไม่สามารถวางการซิงโครไนซ์ไว้หลังประเภทการส่งคืนวิธีการได้ ตัวอย่างเช่น รหัสต่อไปนี้ไม่ถูกต้อง:
คัดลอกรหัสรหัสดังต่อไปนี้:
โมฆะสาธารณะวิธีการซิงโครไนซ์ ();
โมฆะสาธารณะวิธีการซิงโครไนซ์แบบคงที่ ();
คำสำคัญที่ซิงโครไนซ์สามารถใช้เพื่อซิงโครไนซ์วิธีการเท่านั้น ไม่ใช่ตัวแปรคลาส รหัสต่อไปนี้ก็ผิดเช่นกัน
คัดลอกรหัสรหัสดังต่อไปนี้:
สาธารณะซิงโครไนซ์ int n = 0;
สาธารณะคงซิงโครไนซ์ int n = 0;
แม้ว่าการใช้วิธีซิงโครไนซ์คำสำคัญที่ซิงโครไนซ์เป็นวิธีการซิงโครไนซ์ที่ปลอดภัยที่สุด แต่การใช้คำสำคัญที่ซิงโครไนซ์อย่างกว้างขวางจะทำให้เกิดการใช้ทรัพยากรโดยไม่จำเป็นและสูญเสียประสิทธิภาพ แม้ว่าบนพื้นผิวดูเหมือนว่าการซิงโครไนซ์ล็อควิธีการ แต่ในความเป็นจริงแล้วซิงโครไนซ์ล็อคคลาส กล่าวอีกนัยหนึ่ง หากใช้การซิงโครไนซ์เมื่อกำหนดทั้งวิธีที่ 1 และวิธีที่ 2 แบบไม่คงที่ จะไม่สามารถดำเนินการวิธีที่ 2 ได้ก่อนที่จะดำเนินการวิธีที่ 1 สถานการณ์จะคล้ายกันสำหรับวิธีการแบบคงที่และไม่คงที่ แต่วิธีการแบบคงที่และไม่คงที่จะไม่ส่งผลกระทบต่อกัน ลองดูรหัสต่อไปนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
การทดสอบบรรจุภัณฑ์
MyThread1 คลาสสาธารณะขยายเธรด
-
methodName สตริงสาธารณะ;
วิธีการโมฆะคงสาธารณะ (สตริง s)
-
System.out.println(s);
ในขณะที่(จริง)
-
โมฆะการซิงโครไนซ์สาธารณะ method1 ()
-
วิธีการ ("วิธีที่ไม่คงที่ 1 วิธีการ");
-
โมฆะการซิงโครไนซ์สาธารณะ method2 ()
-
method("วิธี non-static method2");
-
โมฆะการซิงโครไนซ์สาธารณะแบบคงที่ method3 ()
-
วิธีการ ("วิธีคงที่ 3 วิธี");
-
โมฆะการซิงโครไนซ์สาธารณะแบบคงที่ method4 ()
-
วิธีการ ("วิธีคงที่ method4");
-
การรันโมฆะสาธารณะ ()
-
พยายาม
-
getClass().getMethod(methodName).inurge(นี่);
-
จับ (ยกเว้น e)
-
-
-
โมฆะคงที่สาธารณะ main (String [] args) พ่นข้อยกเว้น
-
MyThread1 myThread1 = ใหม่ MyThread1();
สำหรับ (int i = 1; i <= 4; i++)
-
myThread1.methodName = "วิธีการ" + String.valueOf(i);
เธรดใหม่ (myThread1).start();
นอน(100);
-
-
-
ผลการวิ่งมีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
วิธีที่ไม่คงที่1 วิธี
วิธีคงที่ 3 วิธี
ดังที่เห็นได้จากผลการรันข้างต้น วิธีที่ 2 และวิธีที่ 4 ไม่สามารถทำงานได้ก่อนที่วิธีที่ 1 และวิธีที่ 3 จะเสร็จสมบูรณ์ ดังนั้น เราสามารถสรุปได้ว่า ถ้าคุณใช้คีย์เวิร์ดที่ซิงโครไนซ์เพื่อกำหนดวิธีการที่ไม่คงที่ในคลาส มันจะส่งผลต่อวิธีการที่ไม่คงที่ทั้งหมดที่กำหนดโดยใช้คีย์เวิร์ดที่ซิงโครไนซ์ในคลาสนี้ หากมีการกำหนดวิธีการคงที่ จะส่งผลต่อวิธีการคงที่ทั้งหมดที่กำหนดโดยใช้คำสำคัญที่ซิงโครไนซ์ในชั้นเรียน นี่เป็นเหมือนการล็อคตารางในตารางข้อมูลเล็กน้อย เมื่อมีการแก้ไขบันทึก ระบบจะล็อคทั้งตาราง ดังนั้น การใช้วิธีการซิงโครไนซ์อย่างกว้างขวางจะลดประสิทธิภาพของโปรแกรมลงอย่างมาก