Java Concurrency - การหยุดชะงัก

Deadlock อธิบายถึงสถานการณ์ที่เธรดสองเธรดขึ้นไปถูกบล็อกตลอดไปโดยรอกันและกัน การหยุดชะงักเกิดขึ้นเมื่อเธรดหลายเธรดต้องการการล็อกเดียวกัน แต่ได้รับในลำดับที่ต่างกัน โปรแกรมมัลติเธรด Java อาจได้รับผลกระทบจากสภาวะชะงักงันเนื่องจากไฟล์synchronizedคีย์เวิร์ดทำให้เธรดการเรียกใช้บล็อกขณะรอการล็อกหรือมอนิเตอร์ที่เชื่อมโยงกับอ็อบเจ็กต์ที่ระบุ นี่คือตัวอย่าง

ตัวอย่าง

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();
   
   public static void main(String args[]) {
      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }
   
   private static class ThreadDemo1 extends Thread {
   
      public void run() {
      
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");

            try {
               Thread.sleep(10);
            } catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");

            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }

   private static class ThreadDemo2 extends Thread {
   
      public void run() {
      
         synchronized (Lock2) {
            System.out.println("Thread 2: Holding lock 2...");
            
            try {
               Thread.sleep(10);
            } catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 1...");
            
            synchronized (Lock1) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

เมื่อคุณคอมไพล์และรันโปรแกรมข้างต้นคุณจะพบสถานการณ์ชะงักงันและต่อไปนี้คือผลลัพธ์ที่สร้างโดยโปรแกรม -

เอาต์พุต

Thread 1: Holding lock 1...
Thread 2: Holding lock 2...
Thread 1: Waiting for lock 2...
Thread 2: Waiting for lock 1...

โปรแกรมด้านบนจะหยุดทำงานตลอดไปเนื่องจากเธรดทั้งสองไม่อยู่ในตำแหน่งที่จะดำเนินการต่อและรอให้กันและกันคลายล็อกคุณจึงสามารถออกจากโปรแกรมได้โดยกด CTRL + C

ตัวอย่างโซลูชัน Deadlock

มาเปลี่ยนลำดับการล็อกและรันโปรแกรมเดียวกันเพื่อดูว่าเธรดทั้งสองยังรอกันอยู่หรือไม่ -

ตัวอย่าง

public class TestThread {
   public static Object Lock1 = new Object();
   public static Object Lock2 = new Object();
   
   public static void main(String args[]) {
      ThreadDemo1 T1 = new ThreadDemo1();
      ThreadDemo2 T2 = new ThreadDemo2();
      T1.start();
      T2.start();
   }
   
   private static class ThreadDemo1 extends Thread {
   
      public void run() {
         
         synchronized (Lock1) {
            System.out.println("Thread 1: Holding lock 1...");
            
            try {
               Thread.sleep(10);
            } catch (InterruptedException e) {}
            System.out.println("Thread 1: Waiting for lock 2...");

            synchronized (Lock2) {
               System.out.println("Thread 1: Holding lock 1 & 2...");
            }
         }
      }
   }

   private static class ThreadDemo2 extends Thread {
      
      public void run() {
         
         synchronized (Lock1) {
            System.out.println("Thread 2: Holding lock 1...");
           
            try {
               Thread.sleep(10);
            } catch (InterruptedException e) {}
            System.out.println("Thread 2: Waiting for lock 2...");

            synchronized (Lock2) {
               System.out.println("Thread 2: Holding lock 1 & 2...");
            }
         }
      }
   } 
}

ดังนั้นการเปลี่ยนลำดับของการล็อกจะป้องกันไม่ให้โปรแกรมเข้าสู่สถานการณ์ชะงักงันและดำเนินการตามผลลัพธ์ต่อไปนี้ -

เอาต์พุต

Thread 1: Holding lock 1...
Thread 1: Waiting for lock 2...
Thread 1: Holding lock 1 & 2...
Thread 2: Holding lock 1...
Thread 2: Waiting for lock 2...
Thread 2: Holding lock 1 & 2...

ตัวอย่างข้างต้นเป็นเพียงการทำให้แนวคิดชัดเจน แต่เป็นแนวคิดที่ซับซ้อนและคุณควรเจาะลึกลงไปก่อนที่จะพัฒนาแอปพลิเคชันของคุณเพื่อรับมือกับสถานการณ์การชะงัก