1. เกิดปัญหาแบบซิงโครนัส
การซิงโครไนซ์เธรดคือการป้องกันความเสียหายต่อข้อมูลเมื่อหลายเธรดเข้าถึงวัตถุข้อมูล
ตัวอย่างเช่น: ทั้งสองเธรด Threada และ Threadb ทำงานวัตถุ Foo เดียวกันและแก้ไขข้อมูลบนวัตถุ Foo
แพ็คเกจ cn.thread; คลาสสาธารณะ foo {ส่วนตัว int x = 100; สาธารณะ int getx () {return x; } public int fix (int y) {x = x - y; กลับ x; - แพ็คเกจ cn.thread; คลาสสาธารณะ myrunnable ดำเนินการ runnable {private foo foo = new foo (); โมฆะคงที่สาธารณะหลัก (สตริง [] args) {myrunnable run = new myrunnable (); เธรด ta = เธรดใหม่ (run, "thread-a"); เธรด tb = เธรดใหม่ (run, "thread-b"); ta.start (); tb.start (); } โมฆะสาธารณะเรียกใช้ () {สำหรับ (int i = 0; i <3; i ++) {this.fix (30); ลอง {thread.sleep (1); } catch (interruptedException e) {e.printStackTrace (); } system.out.println (thread.currentthread (). getName () + ": ค่า x ของวัตถุ FOO ปัจจุบัน =" + foo.getx ()); }} public int fix (int y) {return foo.fix (y); -ผลการทำงาน:
Thread-B: ค่า x ของวัตถุ FOO ปัจจุบัน = 40
Thread-A: ค่า x ของวัตถุ FOO ปัจจุบัน = 40
Thread -B: ค่า x ของวัตถุ FOO ปัจจุบัน = -20
Thread -A: ค่า x ของวัตถุ FOO ปัจจุบัน = -20
Thread -B: ค่า x ของวัตถุ FOO ปัจจุบัน = -80
Thread -A: ค่า x ของวัตถุ FOO ปัจจุบัน = -80
จากผลลัพธ์พบว่าค่าผลลัพธ์ดังกล่าวไม่สมเหตุสมผลอย่างเห็นได้ชัด เหตุผลก็คือสองเธรดเข้าถึงวัตถุ Foo โดยไม่มีการควบคุมและแก้ไขข้อมูลของพวกเขา
หากคุณต้องการรักษาเหตุผลของผลลัพธ์คุณจะต้องบรรลุเป้าหมายเดียวเท่านั้นซึ่งคือการ จำกัด การเข้าถึง Foo และมีเพียงหนึ่งเธรดเท่านั้นที่สามารถเข้าถึงได้ในแต่ละครั้ง สิ่งนี้จะช่วยให้มั่นใจถึงความมีเหตุผลของข้อมูลในวัตถุ Foo
ในรหัส Java ที่เฉพาะเจาะจงจะต้องดำเนินการสองครั้ง:
ระบุตัวแปร FOO X ของคลาสทรัพยากรที่เข้าชมโดยการแข่งขันเป็นส่วนตัว
ซิงโครไนซ์รหัสที่ปรับเปลี่ยนตัวแปรและใช้คำหลักที่ซิงโครไนซ์เพื่อซิงโครไนซ์เมธอดหรือรหัส
แพ็คเกจ CN.THREAD; คลาสสาธารณะ FOO2 {ส่วนตัว int x = 100; สาธารณะ int getx () {return x; } // วิธีการซิงโครไนซ์สาธารณะที่ซิงโครไนซ์ int fix (int y) {x = x - y; System.out.println ("เธรด" + thread.currentthread (). getName () + "สิ้นสุดลง, ลด" " + y +" ", ค่าปัจจุบันคือ:" + x); กลับ x; } // // บล็อกรหัสซิงโครไนซ์ // public int fix (int y) {// ซิงโครไนซ์ (นี่) {// x = x - y; // system.out.println ("เธรด" + เธรด. แพ็คเกจ cn.thread; คลาสสาธารณะ myrunnable2 {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {myrunnable2 run = new myrunnable2 (); foo2 foo2 = new foo2 (); MYTHREAD T1 = Run.New MyThread ("Thread A", foo2, 10); MYTHREAD T2 = Run.New MyThread ("Thread B", FOO2, -2); MYTHREAD T3 = Run.New MyThread ("Thread C", FOO2, -3); MYTHREAD T4 = RUN.NEW MYTHREAD ("Thread D", FOO2, 5); t1.start (); t2.start (); t3.start (); t4.start (); } คลาส MyThread ขยายเธรด {ส่วนตัว foo2 foo2; / ** ค่าปัจจุบัน*/ ส่วนตัว int y = 0; MyThread (ชื่อสตริง, foo2 foo2, int y) {super (ชื่อ); this.foo2 = foo2; this.y = y; } public void run () {foo2.fix (y); - เธรดการรันสิ้นสุดลด "10" ค่าปัจจุบันคือ: 90
เธรด C ทำงานและสิ้นสุดลด "-3" ค่าปัจจุบันคือ: 93
เธรด B ทำงานที่ปลายลด "-2" ค่าปัจจุบันคือ: 95
เธรด D ทำงานและสิ้นสุดลด "5" ค่าปัจจุบันคือ: 90
2. การซิงโครไนซ์และล็อค
1. หลักการล็อค
แต่ละวัตถุในชวามีล็อคในตัว
เมื่อโปรแกรมทำงานบนวิธีการซิงโครไนซ์แบบซิงโครไนซ์แบบไม่คงที่การล็อคที่เชื่อมโยงกับอินสแตนซ์ปัจจุบันของคลาสรหัสที่กำลังดำเนินการ (อินสแตนซ์นี้) ล็อคที่ได้รับวัตถุเรียกอีกอย่างว่าการล็อคการล็อควัตถุล็อควัตถุหรือการซิงค์บนวัตถุ
การล็อควัตถุจะทำงานเฉพาะเมื่อโปรแกรมทำงานเป็นวิธีการซิงโครไนซ์ซิงโครไนซ์หรือบล็อกรหัส
มีเพียงล็อคเดียวสำหรับวัตถุ ดังนั้นหากเธรดได้รับล็อคจะไม่มีเธรดอื่นใดที่สามารถรับล็อคได้จนกว่าเธรดแรกจะปล่อย (หรือส่งคืน) ล็อค นอกจากนี้ยังหมายความว่าไม่มีเธรดอื่นใดที่สามารถป้อนวิธีการซิงโครไนซ์หรือบล็อกรหัสบนวัตถุจนกว่าจะมีการปล่อยล็อค
การปล่อยล็อคหมายความว่าเธรดล็อคออกจากวิธีการซิงโครไนซ์ซิงโครไนซ์หรือบล็อกรหัส
มีประเด็นสำคัญบางประการเกี่ยวกับการล็อคและการซิงโครไนซ์:
1) วิธีการเท่านั้นที่สามารถซิงโครไนซ์ได้ แต่ตัวแปรและคลาสไม่สามารถซิงโครไนซ์ได้
2) แต่ละวัตถุมีเพียงล็อคเดียว เมื่อพูดถึงการซิงโครไนซ์ควรมีอะไรชัดเจน? นั่นคือการซิงโครไนซ์วัตถุใด
3) ไม่จำเป็นต้องซิงโครไนซ์ทุกวิธีในชั้นเรียน ชั้นเรียนสามารถมีทั้งวิธีการแบบซิงโครนัสและแบบอะซิงโครนัส
4) หากสองเธรดต้องการเรียกใช้วิธีการซิงโครไนซ์ในคลาสเดียวและสองเธรดใช้อินสแตนซ์เดียวกันเพื่อเรียกวิธีการนั้นมีเพียงเธรดเดียวเท่านั้นที่สามารถเรียกใช้วิธีการครั้งละหนึ่งและต้องรอจนกว่าล็อคจะถูกปล่อยออกมา นั่นคือ: หากเธรดได้รับการล็อคบนวัตถุไม่มีเธรดอื่นใดที่สามารถป้อนวิธีการซิงโครไนซ์ใด ๆ ในคลาส (ของวัตถุนั้น)
5) หากเธรดมีการซิงโครไนซ์และวิธีการแบบอะซิงโครนัสวิธีการแบบอะซิงโครนัสสามารถเข้าถึงได้อย่างอิสระโดยหลายเธรดโดยไม่ถูก จำกัด โดยล็อค
6) เมื่อเธรดนอนหลับจะไม่มีการล็อคไว้จะถูกปล่อยออกมา
7) เธรดสามารถรับล็อคได้หลายตัว ตัวอย่างเช่นการเรียกใช้วิธีการซิงโครไนซ์ของวัตถุอื่นในวิธีการซิงโครไนซ์ของวัตถุหนึ่งจะได้รับการล็อคการซิงโครไนซ์ของวัตถุทั้งสอง
8) การซิงโครไนซ์ทำให้เกิดการเกิดขึ้นพร้อมกันและควร จำกัด ช่วงการซิงโครไนซ์ให้แคบลงให้มากที่สุด การซิงโครไนซ์ไม่เพียง แต่ซิงโครไนซ์วิธีทั้งหมดเท่านั้น แต่ยังซิงโครไนซ์บางบล็อกในเมธอด
9) เมื่อใช้บล็อกรหัสการซิงโครไนซ์คุณควรระบุว่าวัตถุใดที่จะซิงโครไนซ์นั่นคือการล็อคของวัตถุที่จะได้รับ ตัวอย่างเช่น:
public int fix (int y) {ซิงโครไนซ์ (นี่) {x = x - y; } return x;} แน่นอนว่าวิธีการซิงโครไนซ์ยังสามารถเขียนใหม่เป็นวิธีแบบอะซิงโครนัสได้ แต่ฟังก์ชั่นนั้นเหมือนกันทุกประการเช่น:
public synchronized int getx () {return x ++;} และ
สาธารณะ int getx () {ซิงโครไนซ์ (นี่) {return x ++; -เอฟเฟกต์เหมือนกันทุกประการ
3. การซิงโครไนซ์วิธีการแบบคงที่
ในการซิงโครไนซ์วิธีการคงที่จำเป็นต้องมีการล็อคสำหรับวัตถุคลาสทั้งหมดซึ่งเป็นคลาสนี้ (xxx.class)
ตัวอย่างเช่น:
setName int synchronized สาธารณะ (ชื่อสตริง) {xxx.name = name;}
เทียบเท่ากับ
public Static int setName (ชื่อสตริง) {ซิงโครไนซ์ (xxx.class) {xxx.name = ชื่อ; -4. จะเกิดอะไรขึ้นถ้าเธรดไม่สามารถรับล็อคได้
หากเธรดพยายามป้อนวิธีการแบบซิงโครนัสและล็อคถูกครอบครองเธรดจะถูกบล็อกบนวัตถุ โดยพื้นฐานแล้วเธรดจะเข้าสู่พูลของวัตถุและต้องรอที่จะต้องรอจนกว่าการล็อคจะถูกปล่อยออกมาและเธรดจะทำงานได้หรือทำงานอีกครั้ง
เมื่อพิจารณาการบล็อกให้แน่ใจว่าได้ให้ความสนใจกับวัตถุที่ใช้สำหรับการล็อค:
1. เธรดที่เรียกวิธีการซิงโครไนซ์แบบไม่คงที่ในวัตถุเดียวกันจะปิดกั้นซึ่งกันและกัน หากเป็นวัตถุที่แตกต่างกันแต่ละเธรดมีล็อควัตถุของตัวเองและเธรดจะไม่รบกวนกันและกัน
2. เธรดที่เรียกวิธีการซิงโครไนซ์แบบคงที่ในคลาสเดียวกันจะปิดกั้นซึ่งกันและกันและพวกเขาทั้งหมดถูกล็อคบนวัตถุคลาสเดียวกัน
3. วิธีการซิงโครไนซ์แบบคงที่และวิธีการซิงโครไนซ์แบบไม่คงที่จะไม่ปิดกั้นซึ่งกันและกันเนื่องจากวิธีการคงที่จะถูกล็อคบนวัตถุคลาสในขณะที่วิธีที่ไม่คงที่จะถูกล็อคบนวัตถุของคลาสนี้
4. สำหรับบล็อกรหัสที่ซิงโครไนซ์คุณต้องดูอย่างชัดเจนว่าวัตถุใดที่ใช้สำหรับการล็อค (เนื้อหาของวงเล็บที่ซิงโครไนซ์หลังจากซิงโครไนซ์) เธรดที่ซิงโครไนซ์บนวัตถุเดียวกันจะปิดกั้นซึ่งกันและกันและเธรดที่ถูกล็อคบนวัตถุที่แตกต่างกันจะไม่ปิดกั้นซึ่งกันและกัน
5. เมื่อใดที่จำเป็นต้องซิงโครไนซ์
เมื่อหลายเธรดเข้าถึงข้อมูลพิเศษ (แลกเปลี่ยนได้) พร้อมกันควรซิงโครไนซ์เพื่อปกป้องข้อมูลเพื่อให้แน่ใจว่าเธรดทั้งสองไม่ได้แก้ไขและเปลี่ยนแปลงในเวลาเดียวกัน
สำหรับข้อมูลที่สามารถเปลี่ยนแปลงได้ในเขตข้อมูลที่ไม่คงที่มักจะเข้าถึงวิธีการที่ไม่คงที่
สำหรับข้อมูลที่สามารถเปลี่ยนแปลงได้ในฟิลด์คงที่มักจะเข้าถึงได้โดยใช้วิธีการคงที่
ปัญหามีความซับซ้อนมากหากคุณต้องการใช้ฟิลด์คงที่ในวิธีที่ไม่คงที่หรือเรียกใช้วิธีที่ไม่คงที่ในเขตข้อมูลคงที่ มันเกินขอบเขตของการสอบ SJCP
6. หมวดความปลอดภัยของด้าย
เมื่อคลาสได้รับการซิงโครไนซ์อย่างดีเพื่อปกป้องข้อมูลคลาสนี้เรียกว่า "เธรดที่ปลอดภัย"
แม้สำหรับคลาสที่ปลอดภัยของเธรดคุณควรระวังให้มากเพราะเธรดที่ทำงานยังไม่ปลอดภัย
7. สรุปการซิงโครไนซ์เธรด
1. จุดประสงค์ของการซิงโครไนซ์เธรดคือการปกป้องความเสียหายต่อทรัพยากรเมื่อหลายเธรดเข้าถึงทรัพยากร
2. วิธีการซิงโครไนซ์เธรดถูกนำไปใช้ผ่านล็อค แต่ละวัตถุมีเพียงล็อคเดียว ล็อคนี้เกี่ยวข้องกับวัตถุเฉพาะ เมื่อเธรดได้รับการล็อควัตถุเธรดอื่น ๆ ที่เข้าถึงวัตถุจะไม่สามารถเข้าถึงวิธีการซิงโครไนซ์อื่น ๆ ของวัตถุได้อีกต่อไป
3. สำหรับวิธีการซิงโครไนซ์แบบคงที่ล็อคสำหรับคลาสนี้และล็อควัตถุเป็นวัตถุคลาสของคลาสนี้ การล็อคของวิธีการคงที่และไม่คงที่ไม่รบกวนกันและกัน เธรดจะได้รับการล็อคและเมื่อเข้าถึงวิธีการซิงโครไนซ์บนวัตถุอื่นในวิธีการซิงโครไนซ์จะได้รับการล็อควัตถุทั้งสองนี้
4. สำหรับการซิงโครไนซ์มันเป็นกุญแจสำคัญที่จะต้องทราบเสมอว่าวัตถุใดที่จะซิงโครไนซ์
5. เมื่อเขียนคลาสที่ปลอดภัยจากเธรดคุณต้องใส่ใจในการตัดสินที่ถูกต้องเกี่ยวกับตรรกะและความปลอดภัยของหลายเธรดที่แข่งขันกันเพื่อเข้าถึงทรัพยากรวิเคราะห์การดำเนินงาน "อะตอม" และตรวจสอบให้แน่ใจว่าหัวข้ออื่น ๆ ไม่สามารถเข้าถึงทรัพยากรการแข่งขันในระหว่างการดำเนินการปรมาณู
6. เมื่อหลายเธรดกำลังรอล็อควัตถุเธรดที่ไม่ได้รับการล็อคจะบล็อก
7. การหยุดชะงักเกิดจากเธรดที่รอให้กันล็อคและความน่าจะเป็นของการเกิดขึ้นในความเป็นจริงนั้นเล็กมาก หากคุณต้องการเขียนโปรแกรมหยุดชะงักจริงๆมันอาจจะไม่ง่ายเลยฮ่าฮ่า อย่างไรก็ตามเมื่อโปรแกรมตายโปรแกรมจะตาย
ลิงค์ดั้งเดิม: http://www.cnblogs.com/linjiqin/p/3208843.html
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น