× Giới thiệu Lịch khai giảng Tin tức Sản phẩm học viên

Deadlock trong Java - Cách tránh Deadlock trong lập trình Java

13/09/2021 01:07

Chúng ta biết rằng Java hỗ trợ một trong những khái niệm lập trình quan trọng nhất là đa luồng. Đa luồng là một quá trình thực hiện nhiều luồng cùng lúc. Nhưng trong đa luồng, có một vấn đề mà lập trình viên có thể gặp là khi các luồng chuyển sang trạng thái chờ và không thể thực hiện được mà bị chặn mãi mãi. Đây được gọi là deadlock trong Java. Trong bài viết này, chúng ta sẽ tìm hiểu rõ về khái niệm deadlock trong Java, cách chúng ta có thể phát hiện cũng như tránh được Deadlock trong Java.

Khái niệm Deadlock trong Java

Deadlock trong Java là một điều kiện khi hai hoặc nhiều luồng cố gắng truy cập vào cùng một tài nguyên tại cùng một khoảng thời gian. Sau đó, các luồng này không bao giờ có thể truy cập tài nguyên nữa mà bị chuyển sang trạng thái chờ mãi  mãi. Vì vậy, deadlock phát sinh khi có nhiều hơn hai luồng hoặc hơn hai nguồn. Về cơ bản, deadlock xảy ra khi đa luồng yêu cầu cùng một nguồn nhưng chúng được nhận theo thứ tự khác nhau. Cuối cùng, chúng bị mắc kẹt trong một khoảng thời gian vô hạn và tạo ra deadlock.

 

Deadlock trong Java

>>> Tham khảo: Khóa học lập trình Java

Ví dụ về Deadlock trong Java

package com.techvidvan.deadlock;

public class DeadlockDemo {

  public static void main(String[] args) {

    final String resource1 = "Techvidvan ";

    final String resource2 = "Java Tutorial";




    Thread t1 = new Thread() {

      public void run() {

        synchronized(resource1) {

          System.out.println("Thread 1: Locked resource1");

          try {

            Thread.sleep(100);

          }

          catch(Exception e) {}

          synchronized(resource2) {

            System.out.println("Thread 1: Locked resource2");

          }

        }

      }

    };

    Thread t2 = new Thread() {

      public void run() {

        synchronized(resource1) {

          System.out.println("Thread 2: Locked resource1");

          try {

            Thread.sleep(100);

          } catch(Exception e) {}

          synchronized(resource2) {

            System.out.println("Thread 2: Locked resource2");

          }




        }

      }

    };




    t1.start();

    t2.start();

  }

}

Output

>>> Đọc thêm: Ép kiểu trong Java - Giải mã thông tin về Java type conversion

 

Cách phát hiện Deadlock trong Java

Chúng ta có thể phát hiện deadlock trong Java trong hệ thống bằng cách chạy chương trình trên và tìm kiếm trong ứng dụng Java Thread Dump. Chúng ta có thể chạy chương trình trong câu lệnh và thu thập kết xuất luồng và tùy thuộc vào Hệ điều hành, chúng ta có thể tạo kết xuất luồng bằng các lệnh. Để lấy quá trình PID, chúng ta nhận lệnh jps và sau đó chúng ta nhận được PID của quá trình đang chạy. Để lấy luồng kết xuất, chúng ta sẽ viết lệnh jcmd PID Thread .dump để tìm Deadlock. Chúng ta cũng có thể lấy tệp kết xuất này trong tệp văn bản. 

Mặc dù không thể loại bỏ hoàn toàn vấn đề deadlock trong Java nhưng chúng ta có thể thực hiện các biện pháp tránh deadlock như vậy. Các biện pháp phòng ngừa này như sau:

Tránh khóa lồng nhau 

Sử dụng khóa lồng nhau có thể là nguyên nhân chính dẫn đến deadlock trong Java. Chúng ta có thể tránh việc sử dụng khóa lồng nhau để ngăn deadlock trong Java. Khóa lồng nhau có nghĩa là chúng ta cung cấp truy cập từ các nguồn tới đa luồng. Nếu chúng ta đã chỉ định một khóa tới một luồng sau đó chúng ta tránh đứa nó tới một luồng khác.

Tránh các khóa không cần thiết

Chúng ta nên tránh đưa các khóa tới các thành viên hoặc luồng không cần nó. Chúng ta chỉ nên cung cấp khóa tới các luồng quan trọng và tránh sử dụng các khóa không cần thiết. Nếu chúng ta cung cấp một khóa không cần thiết tới một luồng không thực sự cần nó, thì nó có thể dẫn tới deadlock trong Java.

Sử dụng thread joins

Điều kiện dẫn đến deadlock thường xuyên xảy ra khi một luồng đang đợi một luồng khác để hoàn thành thực thi của nó và giữ lấy tài nguyên đó. Trong trường  hợp này, chúng ta có thể sử dụng phương thức Thread,join() và cho nó một khoảng thời gian tối đa mà một luồng cần cần để hoàn thành việc thực thi. Điều này giúp chúng ta loại bỏ nguy cơ xảy ra deadlock trong Java.

>>> Đọc thêm: Singleton trong Java - Cách triển khai và ví dụ mà mọi LTV cần biết

 

Những điểm quan trọng trong Deadlock

  • Nếu hai hoặc ba luồng đang đợi cùng một nguồn hoặc khóa, sau đó nó sẽ là nền tảng dẫn đến deadlock trong Java.
  • Điều kiện dẫn đến deadlock xảy ra chỉ khi môi trường đa luồng nơi đa luồng được thực thi đồng thời.
  • Chúng ta cũng có thể tránh tình huống dẫn đến deadlock bằng cách làm theo một số phương thức ở trên.

Kết luận:

Trong bài viết này, chúng ta đã tìm hiểu về deadlock trong Java - một trong những yếu tố quan trọng trong môi trường đa luồng. Hy vọng bạn có thể hiểu rõ hơn về deadlock để có thể tránh tình trạng này xảy ra trong dự án của mình. Tìm hiểu thêm về Java và các ngôn ngữ lập trình khác, tham khảo thêm các khóa học lập trình tại  Viện công nghệ thông tin T3H.