Java线程优先级<br />需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象X的管程而另一个线程进入了对象Y的管程。如果X的线程试图调用Y的同步方法,它将像预料的一样被锁定。 เธรด y ยังต้องการเรียกวิธีการซิงโครไนซ์บางอย่างของ X และเธรดรอตลอดไปเพราะเพื่อให้ถึง X จะต้องปล่อยล็อคของตัวเองเพื่อให้เธรดแรกเสร็จสมบูรณ์死锁是很难调试的错误,因为:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
มันอาจมีมากกว่าสองเธรดและวัตถุซิงโครนัส (นั่นคือการหยุดชะงักสามารถเกิดขึ้นได้เมื่อมีลำดับเหตุการณ์ที่ซับซ้อนมากกว่าตัวอย่างที่เพิ่งอธิบายไว้)
为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,A和B,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为Deadlock,创建了A和B的实例,然后启动第二个线程去设置死锁环境。 วิธีการ foo () และ bar () ใช้การนอนหลับ () เพื่อบังคับหยุดชะงัก
// ตัวอย่างของ deadlock.class a {void foo synchronized (b b) {string name = thread.currentthread (). getName (); Thread .sleep (1,000); ();} โมฆะซิงโครไนซ์สุดท้าย () {system.out.println ("ภายใน a.last"); System .Out.println (ชื่อ + "ป้อน b.bar"); n (ชื่อ "พยายามเรียก A.last ()"); {a = new a (); (); รับการล็อคในเธรดอื่น ๆ หลังจากเรียกใช้โปรแกรมเอาต์พุตมีดังนี้:
MainThread ป้อน A.FooracingThread เข้าสู่ B.BarmainThread พยายามโทร B.last () RacingThread พยายามโทรหา a.last ()
เนื่องจากโปรแกรมหยุดชะงักคุณต้องกด Ctrl-C เพื่อจบโปรแกรม กด Ctrl-break บนพีซี (หรือกด Ctrl-/ Under Solaris) และคุณสามารถดูเธรดเต็มและฮีปบัฟเฟอร์ไปป์ไลน์ คุณจะเห็นว่า RacingThread ครอบครองกระบวนการจัดการ B ในขณะที่รอกระบวนการจัดการ A และในเวลาเดียวกัน MainThread จะรอการรอกระบวนการจัดการ b โปรแกรมจะไม่สิ้นสุด ดังตัวอย่างนี้แสดงให้เห็นว่าโปรแกรมมัลติเธรดของคุณมักถูกล็อคและการหยุดชะงักเป็นปัญหาแรกที่คุณควรตรวจสอบ
Java Thread Deadlock <br /> ข้อผิดพลาดพิเศษที่เกี่ยวข้องกับการทำงานหลายอย่างที่ต้องหลีกเลี่ยงคือการหยุดชะงัก การหยุดชะงักเกิดขึ้นเมื่อสองเธรดมีการพึ่งพาเป็นวงกลมกับคู่ของวัตถุซิงโครนัส ตัวอย่างเช่นสมมติว่าหนึ่งเธรดเข้าสู่ไปป์ไลน์ของวัตถุ X และเธรดอื่นเข้าสู่ไปป์ไลน์ของวัตถุ Y หากเธรดของ X พยายามเรียกวิธีการซิงโครไนซ์ของ Y มันจะถูกล็อคตามที่คาดไว้ เธรด y ยังต้องการเรียกวิธีการซิงโครไนซ์บางอย่างของ X และเธรดรอตลอดไปเพราะเพื่อให้ถึง X จะต้องปล่อยล็อคของตัวเองเพื่อให้เธรดแรกเสร็จสมบูรณ์ Deadlock เป็นข้อผิดพลาดที่ยากมากในการดีบักเพราะ:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
มันอาจมีมากกว่าสองเธรดและวัตถุซิงโครนัส (นั่นคือการหยุดชะงักสามารถเกิดขึ้นได้เมื่อมีลำดับเหตุการณ์ที่ซับซ้อนมากกว่าตัวอย่างที่เพิ่งอธิบายไว้)
เพื่อให้เข้าใจการหยุดชะงักอย่างเต็มที่มันมีประโยชน์ในการสังเกตพฤติกรรมของมัน ตัวอย่างต่อไปนี้สร้างสองคลาส A และ B โดยมีวิธีการ foo () และ bar () ตามลำดับ ทั้งสองวิธีนี้มีการหยุดสั้น ๆ ก่อนที่จะโทรหาวิธีการเรียนอื่น ๆ คลาสหลักชื่อ Deadlock สร้างอินสแตนซ์ของ A และ B จากนั้นเริ่มเธรดที่สองเพื่อตั้งค่าสภาพแวดล้อมการหยุดชะงัก วิธีการ foo () และ bar () ใช้การนอนหลับ () เพื่อบังคับหยุดชะงัก
// An example of deadlock.class A { synchronized void foo(B b) { String name = Thread.currentThread().getName(); System.out.println(name + " entere d A.foo"); try { Thread .sleep (1,000); ();} โมฆะซิงโครไนซ์สุดท้าย () {system.out.println ("ภายใน a.last"); System .Out.println (ชื่อ + "ป้อน b.bar"); n (ชื่อ "พยายามเรียก A.last ()"); {a = new a (); (); รับการล็อคในเธรดอื่น ๆ หลังจากเรียกใช้โปรแกรมเอาต์พุตมีดังนี้:
MainThread ป้อน A.FooracingThread เข้าสู่ B.BarmainThread พยายามโทร B.last () RacingThread พยายามโทรหา a.last ()
เนื่องจากโปรแกรมหยุดชะงักคุณต้องกด Ctrl-C เพื่อจบโปรแกรม กด Ctrl-break บนพีซี (หรือกด Ctrl-/ Under Solaris) และคุณสามารถดูเธรดเต็มและฮีปบัฟเฟอร์ไปป์ไลน์ คุณจะเห็นว่า RacingThread ครอบครองกระบวนการจัดการ B ในขณะที่รอกระบวนการจัดการ A และในเวลาเดียวกัน MainThread จะรอการรอกระบวนการจัดการ b โปรแกรมจะไม่สิ้นสุด ดังตัวอย่างนี้แสดงให้เห็นว่าโปรแกรมมัลติเธรดของคุณมักถูกล็อคและการหยุดชะงักเป็นปัญหาแรกที่คุณควรตรวจสอบ