คำหลักที่ซิงโครไนซ์แสดงให้เห็นว่าวิธีนี้ถูกล็อค มันเทียบเท่ากับไม่ว่าเธรดใด (เช่นเธรด A) เมื่อเรียกใช้วิธีนี้คุณต้องตรวจสอบว่าเธรดอื่น B (หรือ C, D ฯลฯ ) กำลังใช้วิธีนี้ (หรือวิธีการซิงโครไนซ์อื่น ๆ ของคลาสนี้) ถ้าเป็นเช่นนั้นรอเธรด B (หรือ C, D) ที่ใช้วิธีการซิงโครไนซ์เพื่อเรียกใช้วิธีนี้ก่อนที่จะเรียกใช้วิธีนี้ ถ้าไม่ล็อคผู้โทรและเรียกใช้โดยตรง มันมีสองการใช้งาน: วิธีการซิงโครไนซ์และบล็อกซิงโครไนซ์
กลไกการซิงโครไนซ์แบบมัลติเธรดล็อคทรัพยากรเพื่อให้ในเวลาเดียวกันมีเพียงเธรดเดียวเท่านั้นที่สามารถใช้งานได้และการซิงโครไนซ์จะใช้เพื่อแก้ปัญหาที่อาจเกิดขึ้นเมื่อหลายเธรดเข้าถึงพร้อมกัน
กลไกการซิงโครไนซ์สามารถใช้งานได้โดยใช้คำหลักที่ซิงโครไนซ์
เมื่อคำหลักที่ซิงโครไนซ์ปรับเปลี่ยนวิธีการวิธีนี้เรียกว่าวิธีการซิงโครไนซ์
เมื่อวิธีการซิงโครไนซ์ถูกดำเนินการหรือมีข้อยกเว้นเกิดขึ้นล็อคจะถูกปล่อยออกมาโดยอัตโนมัติ
ต่อไปนี้เป็นตัวอย่างในการวิเคราะห์การใช้คำหลักที่ซิงโครไนซ์
1. การใช้คำหลักที่ซิงโครไนซ์
ตัวอย่างโปรแกรม 1
Public Class ThreadTest {โมฆะสาธารณะคงที่หลัก (String [] args) {ตัวอย่าง = ตัวอย่างใหม่ (); เธรด t1 = ใหม่เธรด 1 (ตัวอย่าง); เธรด t2 = ใหม่เธรด 1 (ตัวอย่าง); t1.start (); t2.start (); }} ตัวอย่างคลาส {public synchronized void execute () {สำหรับ (int i = 0; i <10; ++ i) {ลอง {thread.sleep (500); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("สวัสดี:" + i); }}} คลาส Thread1 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread1 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะ Run () {example.execute (); - ไม่ว่าจะเป็นการเตรียมคำหลักที่ซิงโครไนซ์ในวิธีการดำเนินการ () ผลการดำเนินการของโปรแกรมตัวอย่างนี้จะแตกต่างกันมาก
หากคำหลักที่ซิงโครไนซ์ไม่ได้ถูกเพิ่มเธรดทั้งสองจะดำเนินการวิธีการ EXECUTE () ในเวลาเดียวกันและเอาต์พุตเป็นสองกลุ่มพร้อมกัน
หากมีการเพิ่มคำหลักที่ซิงโครไนซ์ชุดของ 0 ถึง 9 จะถูกส่งออกก่อนจากนั้นชุดถัดไปจะเป็นเอาต์พุตแสดงว่าเธรดทั้งสองจะถูกดำเนินการตามลำดับ
2. สถานการณ์มัลติเธรดของหลายวิธี
เปลี่ยนโปรแกรมและเพิ่มวิธีการอื่น Execute2 () เป็นคลาสตัวอย่าง
จากนั้นเขียนเธรดเธรด 2 วิธีการเรียกใช้ () ใน Thread2 Execute Execute2 () ทั้งสองวิธีในคลาสตัวอย่างได้รับการแก้ไขโดยคำหลักที่ซิงโครไนซ์
ตัวอย่างโปรแกรม 2
Public Class ThreadTest {โมฆะสาธารณะคงที่หลัก (String [] args) {ตัวอย่าง = ตัวอย่างใหม่ (); เธรด t1 = ใหม่เธรด 1 (ตัวอย่าง); เธรด t2 = thread2 (ตัวอย่าง); t1.start (); t2.start (); }} ตัวอย่างคลาส {public synchronized void execute () {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("สวัสดี:" + i); }} โมฆะที่ซิงโครไนซ์สาธารณะ execute2 () {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("โลก:" + i); }}} คลาส Thread1 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread1 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะ Run () {example.execute (); }} คลาส Thread2 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread2 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะเรียกใช้ () {example.execute2 (); - หากคำหลักที่ซิงโครไนซ์ถูกลบออกไปสองวิธีจะถูกดำเนินการพร้อมกันและไม่มีอิทธิพลร่วมกัน
แต่ตามที่เขียนไว้ในรูทีนย่อยตัวอย่างแม้แต่สองวิธี:
ผลการดำเนินการจะเป็นเอาต์พุตของเธรดหนึ่งเสมอจากนั้นการดำเนินการของเธรดอื่น
ภาพประกอบ:
หากวัตถุมีวิธีการซิงโครไนซ์หลายวิธีและเธรดได้ป้อนวิธีการซิงโครไนซ์ในช่วงเวลาหนึ่งเธรดอื่น ๆ ไม่สามารถเข้าถึงวิธีการซิงโครไนซ์ใด ๆ ของวัตถุก่อนที่จะดำเนินการวิธีการ
สรุปแล้ว:
เมื่อคำหลักที่ซิงโครไนซ์ปรับเปลี่ยนวิธีการวิธีนี้เรียกว่าวิธีการซิงโครไนซ์
แต่ละวัตถุในชวามีล็อคหรือจอภาพ เมื่อเธรดเข้าถึงวิธีที่ซิงโครไนซ์ของวัตถุวัตถุจะถูกล็อคและไม่มีเธรดอื่นใดที่สามารถเข้าถึงวิธีการซิงโครไนซ์ของวัตถุ (นี่หมายถึงวิธีการซิงโครไนซ์ทั้งหมดไม่ใช่แค่วิธีเดียวกัน) มันไม่ได้จนกว่าเธรดก่อนหน้าจะเสร็จสิ้นวิธีการดำเนินการ (หรือโยนข้อยกเว้น) การล็อคของวัตถุจะถูกปล่อยออกมาเพื่อให้เธรดอื่นสามารถเข้าถึงวิธีการซิงโครไนซ์ของวัตถุอีกครั้ง
โปรดทราบว่าวัตถุถูกล็อคในเวลานี้ หากเป็นวัตถุที่แตกต่างกันไม่มีความสัมพันธ์ที่ จำกัด ระหว่างวัตถุ
เมื่อพยายามสร้างวัตถุเธรดที่สองในรหัสวัตถุตัวอย่างใหม่จะถูกส่งผ่านแล้วไม่มีข้อ จำกัด ระหว่างการดำเนินการของสองเธรด
3. พิจารณาวิธีการซิงโครไนซ์แบบคงที่
เมื่อวิธีการแก้ไขคำหลักที่ซิงโครไนซ์ได้รับการแก้ไขด้วยแบบคงที่ก็มีการกล่าวก่อนหน้านี้ว่าวิธีการซิงโครไนซ์แบบไม่คงที่จะล็อควัตถุ แต่วิธีการคงที่ไม่ได้อยู่ในวัตถุ แต่คลาสและจะล็อควัตถุคลาสของคลาสที่วิธีนี้ตั้งอยู่
ไม่ว่าคลาสจะสร้างวัตถุจำนวนเท่าใดพวกเขาสอดคล้องกับวัตถุคลาสเดียวกัน
ตัวอย่างโปรแกรม 3
Public Class ThreadTest {โมฆะสาธารณะคงที่หลัก (String [] args) {ตัวอย่าง = ตัวอย่างใหม่ (); เธรด t1 = ใหม่เธรด 1 (ตัวอย่าง); // แม้ว่าวัตถุต่าง ๆ จะถูกส่งผ่านที่นี่การซิงโครไนซ์วิธีการคงที่ยังไม่อนุญาตให้หลายเธรดดำเนินการในเวลาเดียวกัน ตัวอย่าง = ใหม่ตัวอย่าง (); เธรด t2 = thread2 (ตัวอย่าง); t1.start (); t2.start (); }} ตัวอย่างคลาส {โมฆะแบบคงที่แบบซิงโครไนซ์สาธารณะ execute () {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("สวัสดี:" + i); }} โมฆะแบบคงที่แบบซิงโครไนซ์สาธารณะ execute2 () {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("โลก:" + i); }}} คลาส Thread1 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread1 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะ Run () {example.execute (); }} คลาส Thread2 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread2 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะเรียกใช้ () {example.execute2 (); - ดังนั้นหากเป็นวิธีการคงที่ (execute () และ execute2 () ทั้งสองมีคำหลักที่เพิ่มเข้ามา) แม้ว่าวัตถุตัวอย่างที่แตกต่างกันจะถูกส่งผ่านไปยังสองเธรดสองเธรดทั้งสองยังคงถูก จำกัด ซึ่งกันและกัน หนึ่งจะต้องดำเนินการก่อนและจากนั้นอีกครั้ง
สรุปแล้ว:
หากวิธีการซิงโครไนซ์เป็นแบบคงที่เมื่อเธรดเข้าถึงวิธีการจะไม่ล็อควัตถุที่วิธีการซิงโครไนซ์อยู่ แต่วัตถุคลาสที่สอดคล้องกับคลาสที่มีวิธีการซิงโครไนซ์ ในชวาไม่ว่าจะมีวัตถุกี่ชิ้นวัตถุเหล่านี้จะสอดคล้องกับวัตถุคลาสที่ไม่ซ้ำกัน ดังนั้นเมื่อเธรดเข้าถึงสองวิธีแบบคงที่และซิงโครไนซ์ของวัตถุสองชิ้นในคลาสเดียวกันลำดับการดำเนินการของพวกเขาก็เป็นลำดับนั่นคือหนึ่งเธรดหนึ่งจะดำเนินการวิธีการก่อนและเธรดอื่น ๆ จะเริ่มหลังจากการดำเนินการเสร็จสมบูรณ์
4. บล็อกซิงโครไนซ์
วิธีการเขียนบล็อกซิงโครไนซ์:
ซิงโครไนซ์ (วัตถุ) {} หมายความว่าเธรดจะล็อควัตถุวัตถุเมื่อดำเนินการ (โปรดทราบว่าวัตถุนี้สามารถเป็นวัตถุของคลาสใดก็ได้หรือคุณสามารถใช้คำหลักนี้ได้)
ด้วยวิธีนี้คุณสามารถระบุวัตถุที่ล็อคได้ด้วยตัวเอง
ตัวอย่างโปรแกรม 4
Public Class ThreadTest {โมฆะสาธารณะคงที่หลัก (String [] args) {ตัวอย่าง = ตัวอย่างใหม่ (); เธรด t1 = ใหม่เธรด 1 (ตัวอย่าง); เธรด t2 = thread2 (ตัวอย่าง); t1.start (); t2.start (); }} ตัวอย่างคลาส {วัตถุส่วนตัว = วัตถุใหม่ (); โมฆะสาธารณะดำเนินการ () {ซิงโครไนซ์ (วัตถุ) {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("สวัสดี:" + i); }}} โมฆะสาธารณะ Execute2 () {ซิงโครไนซ์ (วัตถุ) {สำหรับ (int i = 0; i <20; ++ i) {ลอง {thread.sleep ((ยาว) math.random () * 1000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("โลก:" + i); }}}}} คลาส Thread1 ขยายเธรด {ตัวอย่างส่วนตัว; Public Thread1 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะ Run () {example.execute (); }} คลาส Thread2 ขยายเธรด {ตัวอย่างส่วนตัวตัวอย่าง; Public Thread2 (ตัวอย่างตัวอย่าง) {this.example = ตัวอย่าง; } @Override โมฆะสาธารณะเรียกใช้ () {example.execute2 (); - เอฟเฟกต์ที่ทำได้โดยตัวอย่างโปรแกรม 4 นั้นเหมือนกับของโปรแกรมตัวอย่าง 2 เธรดทั้งสองจะถูกดำเนินการตามลำดับแทนที่จะเป็นพร้อมกัน เมื่อเธรดหนึ่งดำเนินการวัตถุวัตถุจะถูกล็อคและเธรดอื่นไม่สามารถเรียกใช้งานบล็อกที่เกี่ยวข้องได้
วิธีการซิงโครไนซ์นั้นเทียบเท่ากับการห่อข้อความทั้งหมดในวิธีการด้วยบล็อกที่ซิงโครไนซ์แล้วส่งคำหลักนี้ในวงเล็บของบล็อกที่ซิงโครไนซ์ แน่นอนถ้ามันเป็นวิธีการคงที่วัตถุคลาสจะต้องถูกล็อค
บางทีโค้ดเพียงไม่กี่บรรทัดในวิธีการจะเกี่ยวข้องกับปัญหาการซิงโครไนซ์เธรดดังนั้นบล็อกที่ซิงโครไนซ์จะควบคุมการเข้าถึงหลายเธรดมากกว่าวิธีการซิงโครไนซ์ เฉพาะเนื้อหาในบล็อกซิงโครไนซ์ไม่สามารถเข้าถึงได้หลายเธรดในเวลาเดียวกันและข้อความอื่น ๆ ในวิธีการยังสามารถเข้าถึงได้โดยหลายเธรดในเวลาเดียวกัน (รวมถึงก่อนและหลังบล็อกซิงโครไนซ์)
หมายเหตุ: ข้อมูลที่ได้รับการปกป้องโดยการซิงโครไนซ์ควรเป็นส่วนตัว
สรุปแล้ว:
วิธีการซิงโครไนซ์เป็นตัวควบคุมที่มีความละเอียดหยาบ ในช่วงเวลาหนึ่งเธรดเดียวเท่านั้นที่สามารถเรียกใช้วิธีการซิงโครไนซ์
บล็อกที่ซิงโครไนซ์เป็นการควบคุมการเกิดพร้อมกันอย่างละเอียดซึ่งซิงโครไนซ์รหัสในบล็อกเท่านั้น รหัสอื่น ๆ ที่อยู่ในวิธีการและอื่น ๆ นอกเหนือจากบล็อกที่ซิงโครไนซ์สามารถเข้าถึงได้โดยหลายเธรดในเวลาเดียวกัน