JavaRush /จาวาบล็อก /Random-TH /Deadlock ใน Java คืออะไร?
Alexey Smirnov
ระดับ
Москва

Deadlock ใน Java คืออะไร?

เผยแพร่ในกลุ่ม
ระดับความรู้ที่จำเป็นในการทำความเข้าใจบทความ: คุณได้ทำภารกิจ Java Syntax และ Java Core สำเร็จแล้ว และตอนนี้อยู่ในกระบวนการเรียนรู้ Java Multithreading การชะงักงันหรือการชะงักงันใน Java หรือการชะงักงันเป็นข้อผิดพลาดที่เกิดขึ้นเมื่อเธรดมีการขึ้นต่อกันแบบวนบนคู่ของอ็อบเจ็กต์ที่ซิงโครไนซ์ ลองนึกภาพว่าเธรดหนึ่งเข้าไปในออบเจ็กต์มอนิเตอร์xและอีกเธรดหนึ่งเข้าไปในออบเจ็กต์yมอนิเตอร์ ถ้าเธรดในวัตถุxพยายามเรียกวิธีการซิงโครไนซ์บนวัตถุyและวัตถุyในเวลาเดียวกันพยายามเรียกวิธีการซิงโครไนซ์บนวัตถุxเธรดจะค้างอยู่ในการรอ การหยุดชะงักคืออะไร?  - 1ด้านล่างนี้คือตัวอย่างจากบทช่วยสอนเอกสาร Java เกี่ยวกับแนวคิดเรื่องการหยุดชะงัก การบล็อกเธรดเกิดขึ้นที่นี่ที่ไหน?
public class Deadlock {
    static class Friend {
        private final String name;
        public Friend(String name) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }
        public synchronized void bow(Friend bower) {
            System.out.format("%s: %s" + "  has bowed to me!%n", this.name, bower.getName());
            bower.bowBack(this);
        }
        public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
                + " has bowed back to me!%n",
                this.name, bower.getName());
        }
    }

    public static void main(String[] args) {
        final Friend alphonse =
            new Friend("Alphonse");
        final Friend gaston =
            new Friend("Gaston");
        new Thread(new Runnable() {
            @Override
            public void run() {
               // System.out.println("Thread 1");
                alphonse.bow(gaston);
               // System.out.println("Th: gaston bowed to alphonse");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
              //  System.out.println("Thread 2");
                gaston.bow(alphonse);
              //  System.out.println("2.gaston waiting alph bowed");
            }
        }).start();
    }
}
มีสองสิ่งสำคัญที่ต้องทำความเข้าใจที่นี่:
  1. แต่ละเธรดที่ทำงานพร้อมกันทำอะไรกันแน่?
  2. ใช้ล็อคอะไร?
เริ่มจากจุดสิ้นสุดกันก่อน สมมติว่าคุณสร้างวัตถุสองรายการในชั้นเรียนFriend: alphonseและ gastonแต่ละคนมีล็อคของตัวเอง ดังนั้นจึงมีสองล็อคเหล่านี้: gigolos และ gastons เมื่อป้อนวิธีการซิงโครไนซ์ของออบเจ็กต์ การล็อคจะถูกล็อค และเมื่อออกจากวิธีการนั้น จะถูกปล่อย (หรือปลดล็อค) ตอนนี้เกี่ยวกับเธรด เรามาเรียกเธรดแรกกันAlphonse(ด้วยตัวพิมพ์ใหญ่เพื่อแยกความแตกต่างจากอ็อบเจ็กต์อัลฟองส์) นี่คือสิ่งที่มันทำ (ขอเรียกมันAว่า ย่อมาจากAlphonse):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
และนี่คือสิ่งที่เธรดกำลังทำอยู่ในขณะนี้Gaston:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
ทีนี้ลองรวบรวมข้อมูลนี้เข้าด้วยกันแล้วหาคำตอบ เธรดสามารถเชื่อมโยงกัน (นั่นคือเหตุการณ์จะเกิดขึ้น) ในลำดับที่ต่างกัน การหยุดชะงักจะทำงานได้ ตัวอย่างเช่น หากลำดับเป็นดังนี้:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
การหยุดชะงักคืออะไร?  - 2
ในกรณีนี้ เธรดทั้งสองถูกบล็อก และแต่ละเธรดกำลังรอให้อีกเธรดคลายล็อค แต่จะไม่มีใครทำเช่นนี้ เนื่องจากในการทำเช่นนี้ พวกเขาจำเป็นต้องทำวิธีการให้เสร็จสิ้น และมันถูกบล็อกโดยเธรดอื่น ดังนั้นพวกเขาจึงติดอยู่ตรงที่มันเกิดdeadlockขึ้น อย่างไรก็ตาม การทอแบบอื่นก็สามารถทำได้เช่นกัน โดยหนึ่งในเธรดจะมีเวลาทำให้เสร็จก่อนที่จะเริ่มทอที่สอง:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
ในกรณีนี้จะไม่มีการบล็อกเธรดร่วมกัน ตัวอย่างเช่น มีการเพิ่มวิธีการบางอย่างที่ช่วยให้เธรดอื่นมีเวลาดำเนินการ เมื่อผลลัพธ์ขึ้นอยู่กับลำดับของเหตุการณ์ที่เกิดขึ้นพร้อมกัน (ลำดับที่วางแผนไว้หรือความเร็วในการดำเนินการ) กระบวนการดังกล่าวเรียกว่าสภาพการแข่งขันในภาษารัสเซีย - "สภาพการแข่งขัน" สภาพการแข่งขันบางอย่างอาจไม่ทำให้เกิดการหยุดชะงัก อย่างไรก็ตาม จากประสบการณ์ของผม มีเพียงสภาพการแข่งขันเท่านั้นที่ทำให้เกิดภาวะชะงักงัน ตอบโดย: Dave Lillethun
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION