คำถามสัมภาษณ์หลัก Java หลายคำถามมาจากกรอบการเรียนรู้แบบมัลติเธรดและคอลเลกชัน ประสบการณ์การปฏิบัติที่มีความเชี่ยวชาญเป็นสิ่งจำเป็นเมื่อเข้าใจแนวคิดของหัวข้อหลัก บทความนี้รวบรวมคำถามทั่วไปเกี่ยวกับการทำเกลียว Java ซึ่งมักจะถูกถามโดยวิศวกรอาวุโส
0. การซิงโครไนซ์แบบมัลติเธรดใน Java คืออะไร?
ภายใต้โปรแกรมหลายเธรดการซิงโครไนซ์สามารถควบคุมการเข้าถึงทรัพยากรที่ใช้ร่วมกัน หากไม่มีการซิงโครไนซ์เมื่อเธรด Java กำลังแก้ไขตัวแปรที่ใช้ร่วมกันเธรดอื่นจะใช้หรืออัปเดตตัวแปรเดียวกันซึ่งสามารถนำไปสู่ผลลัพธ์ที่ไม่ถูกต้องในโปรแกรมได้อย่างง่ายดาย
1. อธิบายหลายวิธีในการใช้มัลติเธรด?
เธรด Java สามารถใช้อินเทอร์เฟซ Runnable หรือสืบทอดคลาสเธรดเพื่อใช้งานได้ เมื่อคุณวางแผนที่จะรับมรดกหลายครั้งคุณจะต้องการใช้งาน Runnable
2. ความแตกต่างระหว่าง thread.start () และ thread.run () คืออะไร?
เมธอด thread.start () (ดั้งเดิม) เริ่มต้นเธรดและเข้าสู่สถานะพร้อม เมื่อ CPU จัดสรรเวลาให้กับเธรด JVM จะกำหนดวิธีการเรียกใช้วิธีการเรียกใช้ ()
3. ทำไมเราต้องใช้วิธีการเรียกใช้ () และเริ่มต้น ()? เราสามารถใช้วิธีการเรียกใช้ () เพื่อทำงานให้เสร็จได้หรือไม่?
เราต้องการสองวิธีของการเรียกใช้ () & start () เนื่องจาก JVM สร้างเธรดแยกต่างหากที่แตกต่างจากการเรียกใช้วิธีปกติดังนั้นงานนี้จะทำโดยวิธีการเริ่มต้นของเธรด เริ่มต้นใช้งานโดยวิธีการในท้องถิ่นและจำเป็นต้องเรียกอย่างปรากฏ ข้อดีอีกอย่างของการใช้สองวิธีนี้คือวัตถุใด ๆ สามารถเรียกใช้เป็นเธรดได้ ตราบใดที่มีการใช้อินเทอร์เฟซที่รันได้สิ่งนี้จะหลีกเลี่ยงปัญหาการสืบทอดหลายครั้งของ Java ที่เกิดจากการสืบทอดคลาสเธรด
4. คลาส ThreadLocal คืออะไรและใช้อย่างไร?
Threadlocal เป็นตัวแปรท้องถิ่นระดับเธรดไม่ใช่ "เธรดท้องถิ่น" ThreadLocal ให้สำเนาอิสระของตัวแปรสำหรับแต่ละเธรดที่ใช้ตัวแปร แต่ละเธรดไม่ส่งผลกระทบต่อสำเนาของวัตถุเธรดอื่น ๆ เมื่อแก้ไขสำเนา (หมายเหตุของนักแปล)
นี่คือจุดสำคัญของตัวแปรโลคัลเธรด:
ตัวแปรเธรดท้องถิ่น (ตัวแปร ThreadLocal) ให้ตัวแปรแยกต่างหากสำหรับแต่ละเธรด
อินสแตนซ์ Threadlocal มักจะปรากฏในชั้นเรียนเป็นฟิลด์ส่วนตัวแบบคงที่ (ส่วนตัวคงที่) ซึ่งใช้เพื่อเชื่อมโยงเธรด
เมื่อหลายเธรดเข้าถึงอินสแตนซ์เธรดข้อมูลแต่ละเธรดจะเก็บสำเนาอิสระของตัวแปรที่จัดทำโดย ThreadLocal
การใช้งานที่ใช้กันทั่วไปสามารถเห็นได้ในโหมด DAO เมื่อคลาส DAO เป็นคลาส Singleton การเชื่อมต่อฐานข้อมูลจะได้รับการดูแลอย่างอิสระโดยแต่ละเธรดและไม่ส่งผลต่อกันและกัน (Singleton ขึ้นอยู่กับด้าย)
5. เมื่อใดที่ InvalidMonitorStateException จะถูกโยนลงและทำไม?
เมื่อเรียกใช้วิธีการใด ๆ ในการรอ ()/แจ้ง ()/notifyall () หากเธรดปัจจุบันไม่ได้รับการล็อคของวัตถุข้อยกเว้นของการผิดกฎหมายที่ผิดกฎหมายจะถูกโยนลง (นั่นคือเมื่อโปรแกรมไม่ดำเนินการบล็อกการซิงโครไนซ์หรือการซิงโครไนซ์ของวัตถุ เนื่องจากข้อยกเว้นเป็นคลาสย่อยของ RuntimeExCpetion ข้อยกเว้นไม่จำเป็นต้องถูกจับได้ (แม้ว่าคุณจะสามารถจับได้นานเท่าที่คุณต้องการ) ในฐานะที่เป็น runtimeException ข้อยกเว้นดังกล่าวไม่ได้กล่าวถึงในการรอ (), แจ้ง (), NotifyAll () ลายเซ็นเมธอด
6. อะไรคือความแตกต่างระหว่างการนอนหลับ (), ระงับ () และรอ ()?
thread.sleep () ทำให้เธรดปัจจุบันในสถานะ "ไม่สามารถเรียกใช้" ได้ในเวลาที่กำหนด เธรดถือจอภาพของวัตถุเสมอ ตัวอย่างเช่นหากเธรดอยู่ในบล็อกการซิงโครไนซ์หรือวิธีการซิงโครไนซ์เธรดอื่น ๆ ไม่สามารถป้อนบล็อกหรือวิธีการ หากเธรดอื่นเรียกเมธอด interrupt () มันจะตื่นขึ้นมานั้นด้าย "นอนหลับ"
หมายเหตุ: sleep () เป็นวิธีการคงที่ ซึ่งหมายความว่ามันใช้ได้เฉพาะกับเธรดปัจจุบันและข้อผิดพลาดทั่วไปคือการเรียก t.sleep () (นี่คือเธรดที่แตกต่างจากเธรดปัจจุบัน) แม้ว่าจะถูกดำเนินการ t.sleep () แต่เธรดปัจจุบันก็จะนอนหลับไม่ใช่เธรด T T.Suspend () เป็นวิธีที่ล้าสมัย การใช้ Suspend () ทำให้เธรดเข้าสู่สถานะนิ่ง เธรดจะเก็บจอภาพของวัตถุไว้เสมอและ Suspend () มีแนวโน้มที่จะทำให้เกิดปัญหาการหยุดชะงัก
Object.wait () ทำให้เธรดปัจจุบันออกมาจากสถานะ "ไม่สามารถทำได้" ไม่เหมือนกับการนอนหลับ () การรอเป็นวิธีวัตถุแทนที่จะเป็นเธรด เมื่อเรียก object.wait () เธรดก่อนจะต้องได้รับการล็อควัตถุของวัตถุนี้ เธรดปัจจุบันจะต้องเก็บวัตถุล็อคที่ซิงโครไนซ์และเพิ่มเธรดปัจจุบันลงในคิวรอ จากนั้นเธรดอื่นสามารถซิงโครไนซ์วัตถุเดียวกันกับการเรียกใช้ object.notify () ซึ่งจะปลุกเธรดที่เดิมรออยู่แล้วปล่อยล็อค โดยทั่วไปรอ ()/แจ้ง () คล้ายกับการนอนหลับ ()/interrupt () ยกเว้นว่าอดีตต้องการให้วัตถุล็อคที่จะได้รับ
7. จะเกิดอะไรขึ้นเมื่อใช้การซิงโครไนซ์กับวิธีการคงที่?
เมื่อซิงโครไนซ์วิธีการคงที่วัตถุ "คลาส" ของคลาสจะได้รับ ดังนั้นเมื่อเธรดเข้าสู่วิธีการแบบคงที่แบบซิงโครไนซ์มอนิเตอร์เธรดจะได้รับการล็อควัตถุของคลาสเองและเธรดอื่น ๆ ไม่สามารถป้อนวิธีการซิงโครไนซ์แบบคงที่ของคลาสนี้ มันไม่เหมือนวิธีอินสแตนซ์เนื่องจากหลายเธรดสามารถเข้าถึงอินสแตนซ์ที่แตกต่างกันได้วิธีการอินสแตนซ์แบบซิงโครนัสพร้อมกัน
8. เมื่อมีการดำเนินการวิธีการซิงโครไนซ์เธรดสามารถเรียกใช้วิธีการอินซิงโครนัสบนวัตถุได้หรือไม่?
ใช่วิธีการแบบอะซิงโครนัสสามารถเรียกได้โดยไม่มีปัญหาใด ๆ ในความเป็นจริง Java ไม่ได้ทำการตรวจสอบวิธีการแบบอะซิงโครนัสและล็อควัตถุจะถูกตรวจสอบเฉพาะในวิธีการซิงโครไนซ์หรือบล็อกรหัสแบบซิงโครนัส หากวิธีการไม่ได้ประกาศว่าเป็นแบบซิงโครนัสแม้ว่าคุณจะใช้ข้อมูลที่ใช้ร่วมกัน Java จะยังคงเรียกมันว่าโดยไม่ต้องตรวจสอบว่าปลอดภัยหรือไม่ดังนั้นควรระมัดระวังเป็นพิเศษในกรณีนี้ ไม่ว่าจะมีการประกาศวิธีการแบบซิงโครนัสขึ้นอยู่กับการเข้าถึงส่วนที่สำคัญหรือไม่ หากวิธีการไม่สามารถเข้าถึงส่วนที่สำคัญ (ทรัพยากรที่ใช้ร่วมกันหรือโครงสร้างข้อมูล) ไม่จำเป็นต้องประกาศซิงโครนัส
นี่คือตัวอย่าง: คลาสสามัญมีสองวิธีที่ซิงโครไนซ์เมธิด 1 () และวิธีการ 1 () และคลาส MyThread เรียกวิธีการทั้งสองนี้ในเธรดอิสระ
ระดับสาธารณะทั่วไป {สาธารณะที่ซิงโครไนซ์เป็นโมฆะ synchronizedMethod1 () {system.out.println ("synchronizedMethod1 เรียกว่า"); ลอง {thread.sleep (1,000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("SynchronizedMethod1 เสร็จแล้ว"); } โมฆะสาธารณะวิธีการ 1 () {system.out.println ("วิธีที่ 1 เรียกว่า"); ลอง {thread.sleep (1,000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("วิธีการ 1 เสร็จสิ้น"); - ชั้นเรียนสาธารณะ MyThread ขยายเธรด {INT ส่วนตัว ID = 0; สามัญสามัญทั่วไป; Public Mythread (ชื่อสตริง, int no, วัตถุทั่วไป) {super (ชื่อ); สามัญ = วัตถุ; id = ไม่; } โมฆะสาธารณะเรียกใช้ () {system.out.println ("รันเธรด" + this.getName ()); ลอง {ถ้า (id == 0) {Common.synchronizedMethod1 (); } else {Common.method1 (); }} catch (exception e) {e.printstacktrace (); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {สามัญ c = new Common (); MYTHREAD T1 = ใหม่ MYTHREAD ("MYTHREAD-1", 0, C); MYTHREAD T2 = ใหม่ MYTHREAD ("MYTHREAD-2", 1, C); t1.start (); t2.start (); -นี่คือผลลัพธ์ของโปรแกรม:
รัน threadmythread-1
SynchronizedMethod1 เรียก
กำลังรัน ThreadMythread-2
วิธีที่ 1 เรียกว่า
SynchronizedMethod1 ทำ
วิธีที่ 1 เสร็จแล้ว
ผลลัพธ์แสดงให้เห็นว่าแม้ว่าจะมีการเรียกใช้วิธีการซิงโครไนซ์เมธิด 1 () แต่วิธีการ 1 () จะถูกเรียก
9. สองเธรดสามารถเรียกใช้วิธีอินสแตนซ์แบบซิงโครนัสสองวิธีบนวัตถุได้หรือไม่?
ไม่เนื่องจากวัตถุได้ซิงโครไนซ์วิธีการอินสแตนซ์เธรดจึงได้รับการล็อควัตถุของวัตถุ ดังนั้นวิธีการซิงโครไนซ์อื่น ๆ สามารถดำเนินการได้หลังจากวิธีการถูกปล่อยออกมาหลังจากที่การล็อควัตถุถูกปล่อยออกมา ตัวอย่างโค้ดต่อไปนี้ชัดเจนมาก: คลาสทั่วไปมีวิธีการซิงโครไนซ์เมธิด 1 () และวิธีการซิงโครไนซ์เมทโดด 2 () และตำนานเรียกว่าสองวิธีนี้
ระดับสาธารณะทั่วไป {สาธารณะที่ซิงโครไนซ์เป็นโมฆะ synchronizedMethod1 () {system.out.println ("synchronizedMethod1 เรียกว่า"); ลอง {thread.sleep (1,000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("SynchronizedMethod1 เสร็จแล้ว"); } public synchronized void synchronizedMethod2 () {system.out.println ("synchronizedMethod2 เรียกว่า"); ลอง {thread.sleep (1,000); } catch (interruptedException e) {e.printStackTrace (); } system.out.println ("SynchronizedMethod2 DONE"); - ชั้นเรียนสาธารณะ MyThread ขยายเธรด {INT ส่วนตัว ID = 0; สามัญสามัญทั่วไป; Public Mythread (ชื่อสตริง, int no, วัตถุทั่วไป) {super (ชื่อ); สามัญ = วัตถุ; id = ไม่; } โมฆะสาธารณะเรียกใช้ () {system.out.println ("รันเธรด" + this.getName ()); ลอง {ถ้า (id == 0) {Common.synchronizedMethod1 (); } else {Common.synchronizedMethod2 (); }} catch (exception e) {e.printstacktrace (); }} โมฆะคงที่สาธารณะหลัก (สตริง [] args) {สามัญ c = new Common (); MYTHREAD T1 = ใหม่ MYTHREAD ("MYTHREAD-1", 0, C); MYTHREAD T2 = ใหม่ MYTHREAD ("MYTHREAD-2", 1, C); t1.start (); t2.start (); -10. การหยุดชะงักคืออะไร
การหยุดชะงักหมายความว่าสองเธรดหรือมากกว่านั้นถูกบล็อกอย่างไม่สิ้นสุดและเธรดกำลังรอซึ่งกันและกันสำหรับทรัพยากรที่จำเป็น สิ่งนี้สามารถเกิดขึ้นได้เมื่อสองเธรดพยายามที่จะรับล็อคสำหรับทรัพยากรอื่น ๆ และแต่ละเธรดจะรอการเปิดตัวล็อคทรัพยากรอื่น ๆ อย่างไม่มีกำหนดเว้นแต่กระบวนการของผู้ใช้จะถูกยกเลิก เท่าที่ Javaapi เกี่ยวข้องการหยุดชะงักของด้ายอาจเกิดขึ้นในสถานการณ์ต่อไปนี้
11. เธรดที่หิวโหยจนตายและล็อคสดคืออะไร?
แม้ว่าความอดอยากเธรดและการล็อคชีวิตจะไม่ถือว่าเป็นปัญหาที่พบบ่อยเช่นการหยุดชะงัก แต่ก็เป็นเหมือนการเผชิญหน้ากับนักออกแบบการเขียนโปรแกรมพร้อมกัน
เมื่อเธรดทั้งหมดถูกบล็อกหรือไม่สามารถประมวลผลได้เนื่องจากทรัพยากรที่ต้องการไม่ถูกต้องไม่มีเธรดที่ไม่ปิดกั้นเพื่อให้ทรัพยากรพร้อมใช้งาน กระทู้ล็อคสดใน Javaapi อาจเกิดขึ้นในสถานการณ์ต่อไปนี้:
คำถามที่นี่ไม่มีรายละเอียดฉันหวังว่าพวกเขาจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!