Tin Tức

recent

Lỗi deadlock là gì? Khắc phục lỗi deadlock trong java thế nào?

Chúng ta có thể đã biết đến khái niệm deadlock trong các môn khoa học máy tính ở trường đại học hoặc đâu đó trên các bài báo tạp chí chính thực hoặc mạng internet. Nhưng nó chỉ dừng ở mức mô hình khái niệm hoặc thuật toán mà chưa chỉ rõ được trong lập trình deadlock xẩy ra thế nào, khi nào và làm thế nào để tránh lỗi này. Lỗi deadlock này rất nguy hiểm, nếu nó xuất hiện có thể làm chương trình dừng hoạt động, treo ứng dụng. Nếu lỗi xẩy ra ở hệ điều hành sẽ dần đến treo máy nhưng các bạn thường gặp khi sử dụng hệ điều hành Windows

lập trình java cơ bản, lập trình java nâng cao
Mô hình deadlock trong xử lý máy tính​

Trong java, deadlock là trường hợp có ít nhất hai thread(luồng) đang chiếm giữ các tài nguyên khác nhau, và cả hai thread đều đang chờ tài nguyên của bên thứ còn lại để hoàn thành công việc. Và không bên nào chịu giải phóng tài nguyên mà mình đang chiếm giữ. Hãy xem hình dưới đây

lập trình java cơ bản, lập trình java nâng cao

Theo hình trên, Thread-1 đang chiếm giữ tài nguyên A nhưng cần tài nguyên B để hoành thành công việc và tương tự Thread-2 đang chiêm giữ tài nguyên B nhưng cần A để thực hiện công việc

Trong bài viết này, tôi sẽ viết chương trình để tạo tình huống deadlock và đưa ra giải pháp giải quyết lỗi này.

Đây là chương trình java cài đặt theo tinh huống trên:
Mã:
package thread;

public class ResolveDeadLockTest {

    public static void main(String[] args) {
        ResolveDeadLockTest test = new ResolveDeadLockTest();


        final A a = test.new A();
        final B b = test.new B();

        // Thread-1
        Runnable block1 = new Runnable() {
            public void run() {
                synchronized (a) {
                    try {
                        // Dùng phương thức sleep để Thread-1 tạm dừng lại                      
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
   
   
   
                    }
                    // Thread-1 chiếm giữ A nhưng muốn có B
                    synchronized (b) {
                        System.out.println("Thread-1 bị lock");
                    }
                }
            }
        };

        // Thread-2
        Runnable block2 = new Runnable() {
            public void run() {
                synchronized (b) {
                    // Thread-2 chiếm giữ B nhưng cũng muốn có A
                    synchronized (a) {
                        System.out.println("Thread-2 bị lock");
                    }
                }
            }
        };

        new Thread(block1).start();
        new Thread(block2).start();
    }

    // Resource A
    private class A {
        private int i = 10;

        public int getI() {
            return i;
        }

        public void setI(int i) {
            this.i = i;
        }
    }

    // Resource B
    private class B {
        private int i = 20;

        public int getI() {
            return i;
        }

        public void setI(int i) {
            this.i = i;
        }
    }
}
Chạy đoạn mã này chúng ta sẽ nhận thấy lỗi deadlock xẩy ra. Và bây giờ, các bạn hãy cùng tôi khắc phục lỗi này nhé.
Theo kinh nghiệm của tôi, để khắc phục được lỗi triệt để chúng ta phải tìm hiểu và phát hiện ra được nguyên nhân lỗi. Trong tình huống này, nguyên nhân chính là việc tiếp cận và sử dụng tài nguyên A và B. Vì vậy, để giải quyết vấn đề này, chúng ta nên sắp xếp thứ tự tiếp cần và sử dụng tài nguyên của hai thread A và B.

Đoạn mã dưới được viết lại để khắc phục lỗi deadlock
Mã:
   // Thread-1
Runnable block1 = new Runnable() {
    public void run() {
        synchronized (b) {//Thread-1 sẽ chiếm giữ tài nguyên B trước
            try {
                // Dùng phương thức sleep để Thread-1 tạm dừng lại
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // Thread-1 chiếm giữ A nhưng muốn có B
            synchronized (a) {
                System.out.println("Thread-1 bị lock");
            }
        }
    }
};

// Thread-2
Runnable block2 = new Runnable() {
    public void run() {
        synchronized (b) {
            // Thread-2 chiếm giữ B nhưng cũng muốn có A
            synchronized (a) {
                System.out.println("Thread-2 bị lock");
            }
        }
    }
};
Thực hiện chạy đoạn mã này, bạn sẽ không thấy lỗi deadlock xuất hiện nữa. Đến đây tôi hy vọng giải pháp trên sẽ giúp các bạn hiểu được deadlock xẩy ra khi nào và làm thế nào để tránh được lỗi này.

Chúc các bạn giỏi lập trình java.
Happy Learning !!
Lỗi deadlock là gì? Khắc phục lỗi deadlock trong java thế nào? Reviewed by myblog on 21:15:00 Rating: 5

Không có nhận xét nào:

Bản Quyền Thuộc: Blogger JT © 2016. All Rights Reserved
Phát triển bởi JT

Góp Ý Cho JT Blog

Tên

Email *

Thông báo *

Được tạo bởi Blogger.