ชื่อมีดังนี้:
Public Class Testsync2 ใช้งาน Runnable {int b = 100; โมฆะที่ซิงโครไนซ์ M1 () พ่น InterruptedException {B = 1000; Thread.sleep (500); // 6 system.out.println ("b =" + b); } โมฆะที่ซิงโครไนซ์ m2 () พ่น InterruptedException {thread.sleep (250); // 5 b = 2000; } โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่น InterruptedException {testsync2 tt = testsync2 ใหม่ (); เธรด t = เธรดใหม่ (TT); // 1 t.start (); // 2 tt.m2 (); // 3 system.out.println ("เธรดหลัก b =" + tt.b); // 4} @Override โมฆะสาธารณะ Run () {ลอง {m1 (); } catch (interruptedException e) {e.printStackTrace (); -ผลลัพธ์ผลลัพธ์ของโปรแกรมนี้?
ผลลัพธ์ผลลัพธ์ของโปรแกรม
เธรดหลัก b = 2000b = 1,000
หรือ
เธรดหลัก b = 1000b = 1,000
ตรวจสอบคะแนนความรู้
ใน Java โปรแกรมมัลติเธรดเป็นวิธีที่ยากที่สุดที่จะเข้าใจและดีบัก หลายครั้งที่ผลลัพธ์การดำเนินการไม่ได้ดำเนินการตามที่เราจินตนาการไว้ ดังนั้นจึงเป็นเรื่องยากมากที่จะหลายเธรดใน Java ฉันจำได้อย่างคลุมเครือเมื่อฉันเรียนภาษา C ระดับ 2 ในวิทยาลัยคำถามใน ++ คืออะไรและระดับความสำคัญอื่น ๆ อีกมากมายตรงกับผลลัพธ์ผลลัพธ์สุดท้าย ฉันต้องการใช้ลำดับความสำคัญของนักวิ่งและคำถามผสมผสานสำหรับคำถามประเภทนี้ เพียงแค่ท่องมันด้วยการสนับสนุน แต่มัลติเธรด Java ยังคงต้องเข้าใจดีอยู่พนักพิงไม่สามารถทำได้
มาเริ่มการวิเคราะห์สั้น ๆ :
คำถามนี้เกี่ยวข้องกับ 2 เธรด (เธรดหลักเธรดลูก) และคำหลักเกี่ยวข้องกับการซิงโครไนซ์และเธรด
คำหลักที่ซิงโครไนซ์ยังค่อนข้างซับซ้อน (บางครั้งฉันไม่เข้าใจดีดังนั้นคำถามข้างต้นมีความเข้าใจผิดบางอย่าง) ฟังก์ชั่นของมันคือการตระหนักถึงการซิงโครไนซ์เธรด (มีหลายวิธีในการใช้การซิงโครไนซ์เธรดมันเป็นเพียงสิ่งอื่น ๆ ที่บทความติดตามจะพูดคุยเกี่ยวกับการใช้งานบางอย่างของอาจารย์ดั๊กทุ่งหญ้าต้องได้รับการศึกษาอย่างรอบคอบ) งานของมันคือการล็อครหัสที่ต้องการการซิงโครไนซ์เพื่อให้มีเพียงหนึ่งเธรดเท่านั้นที่สามารถเข้าสู่บล็อกการซิงโครไนซ์ในแต่ละครั้ง (อันที่จริงมันเป็นกลยุทธ์ในแง่ร้าย) เพื่อให้แน่ใจว่าเธรดจะจดจำความปลอดภัยเท่านั้น
การใช้คำหลักทั่วไปที่ซิงโครไนซ์
ในรหัสข้างต้นการใช้งานของการซิงโครไนซ์เป็นของกรณีที่สอง ทำหน้าที่โดยตรงกับวิธีการอินสแตนซ์: เทียบเท่ากับการล็อคอินสแตนซ์ปัจจุบัน ก่อนที่จะป้อนรหัสการซิงโครไนซ์คุณจะต้องได้รับการล็อคของอินสแตนซ์ปัจจุบัน
ความเข้าใจผิดที่เป็นไปได้
1. เนื่องจากเราไม่เข้าใจการซิงโครไนซ์หลายครั้งเราจึงใช้วิธีการซิงโครไนซ์โดยมัลติเธรด เมื่อสองเธรดเรียก 2 วิธีที่ซิงโครไนซ์ที่แตกต่างกันก็คิดว่ามันไม่เกี่ยวข้อง ความคิดนี้เข้าใจผิด ทำหน้าที่โดยตรงกับวิธีการอินสแตนซ์: เทียบเท่ากับการล็อคอินสแตนซ์ปัจจุบัน ก่อนที่จะป้อนรหัสการซิงโครไนซ์คุณจะต้องได้รับการล็อคของอินสแตนซ์ปัจจุบัน
2. หากเรียกใช้วิธีการซิงโครไนซ์ การเรียกใช้วิธีปกติอีกวิธีไม่มีอะไรทำและทั้งสองไม่มีความสัมพันธ์ที่รอคอย
สิ่งเหล่านี้มีประโยชน์มากสำหรับการวิเคราะห์ที่ตามมา
Thread.sleep
ปลอดภัยเธรดปัจจุบัน (เช่นเธรดที่เรียกวิธีการ) เป็นระยะเวลาหนึ่งทำให้เธรดอื่นมีโอกาสดำเนินการต่อไป แต่จะไม่ปล่อยล็อควัตถุ กล่าวคือหากการซิงโครไนซ์ซิงโครไนซ์นั้นรวดเร็วเธรดอื่น ๆ ยังไม่สามารถเข้าถึงข้อมูลที่ใช้ร่วมกันได้ โปรดทราบว่าวิธีนี้ต้องจับข้อยกเว้นซึ่งมีประโยชน์มากสำหรับการวิเคราะห์ที่ตามมา
กระบวนการวิเคราะห์
Java ถูกดำเนินการจากวิธีการหลัก ว่ากันว่ามี 2 เธรด แต่แม้ว่าคุณจะปรับเปลี่ยนลำดับความสำคัญของเธรดที่นี่มันก็ไร้ประโยชน์ ลำดับความสำคัญคือเมื่อทั้งสองโปรแกรมยังไม่ได้ดำเนินการ ตอนนี้เมื่อมีการดำเนินการรหัสนี้แล้วเธรดหลักจะถูกดำเนินการแล้ว สำหรับตัวแปรแอตทริบิวต์ int b = 100 จะไม่มีปัญหาการมองเห็นเนื่องจากใช้การซิงโครไนซ์ (และไม่จำเป็นต้องบอกว่าการประกาศผันผวนถูกใช้) เมื่อดำเนินการขั้นตอนที่ 1 (เธรด t = เธรดใหม่ (TT); // 1) เธรดอยู่ในสถานะใหม่และยังไม่ได้เริ่มทำงาน เมื่อมีการดำเนินการ 2 ขั้นตอน (T.Start (); // 2) เมื่อมีการเรียกวิธีการเริ่มต้นเธรดจะเริ่มต้นจริงและเข้าสู่สถานะ Runnable สถานะที่รันได้หมายความว่าสามารถดำเนินการได้และทุกอย่างพร้อม แต่ก็ไม่ได้หมายความว่าจะต้องดำเนินการใน CPU ไม่ว่าจะมีการดำเนินการจริงขึ้นอยู่กับการกำหนดเวลาของ CPU บริการหรือไม่ ที่นี่เมื่อดำเนินการ 3 ขั้นตอนคุณต้องได้รับการล็อคก่อน (เนื่องจากเริ่มต้นต้องเรียกวิธีการดั้งเดิมและทุกอย่างพร้อมหลังจากการใช้งานเสร็จสมบูรณ์ แต่ก็ไม่ได้หมายความว่าจะต้องดำเนินการกับ CPU ไม่ว่าจะมีการดำเนินการจริงขึ้นอยู่กับการกำหนดตารางบริการ CPU ในความเป็นจริงมันไม่สำคัญว่าเธรดจะใช้วิธีการที่ซิงโครไนซ์ทั้งสองหรือไม่มันอาจเพิ่มความยากลำบากในการสับสน เมื่อมีการดำเนินการ 3 ขั้นตอนเธรดเด็กก็พร้อมเร็ว ๆ นี้ แต่เนื่องจากมีการซิงโครไนซ์และทำหน้าที่เป็นวัตถุเดียวกันเธรดลูกจึงต้องรอ เนื่องจากคำสั่งการดำเนินการในวิธีการหลักจะดำเนินการตามลำดับจึงจะต้องเสร็จสิ้นหลังจากขั้นตอนที่ 3 ถูกดำเนินการก่อนที่จะถึงขั้นตอนที่ 4 เนื่องจากการดำเนินการของขั้นตอนที่ 3 เสร็จสมบูรณ์เธรดลูกสามารถดำเนินการ M1 มีปัญหาที่นี่ที่ได้รับมัลติเธรดก่อน หากได้รับ 4 ขั้นตอนก่อนแล้วเธรดหลัก B = 2000 หากได้รับเธรดลูก M1 อาจได้รับการกำหนดให้กับ 1,000 หรือก่อนที่ 4 ขั้นตอนจะถูกกำหนดผลลัพธ์ที่เป็นไปได้คือเธรดหลัก B = 1,000 หรือเธรดหลัก B = 2000 หากมีการลบ 6 ขั้นตอนที่นี่แล้ว b = ดำเนินการก่อนและเธรดหลัก b = ก่อนหน้านี้ไม่แน่นอน อย่างไรก็ตามเนื่องจากมี 6 ขั้นตอนไม่ว่าจะมีเธรดหลัก B = อยู่ข้างหน้าดังนั้นจึงขึ้นอยู่กับสถานการณ์หากมีค่าเท่ากับ 1,000 หรือ 2000 หลังจากนั้น B = 1,000 ได้รับการแก้ไขอย่างแน่นอน
คำแนะนำบางอย่างสำหรับมัลติเธรด
นอกจากนี้ยังมีเคล็ดลับในการแบ่งปันในบทความที่ตามมา มัลติเธรดมีความสำคัญอย่างยิ่งและยาก ฉันหวังว่าทุกคนจะใช้เวลากับมันมากขึ้น
เทคนิคการดีบักบางอย่างสำหรับมัลติเธรด
เนื่องจากเบรกพอยต์เธรดทั้งหมดจำเป็นต้องหยุดเมื่อผ่านจุดพักซึ่งทำให้จุดนี้ถูกขัดจังหวะอย่างต่อเนื่องซึ่งไม่สบายใจมาก มีจุดพักที่มีเงื่อนไขใน Eclispe และคุณสามารถหยุดได้เมื่อมีการปฏิบัติตามเงื่อนไขดังนั้นจึงสะดวก
สรุป
ข้างต้นเป็นคำถามสัมภาษณ์ Java ที่ยากที่สุดในประวัติศาสตร์ที่บรรณาธิการได้แนะนำให้คุณรู้จัก ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!