Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

วิธีป้องกัน Deadlock ใน Java


ใน Java deadlock คือสถานการณ์ที่ เธรด 2 ตัวขึ้นไปบล็อคกันตลอดไป เกิดขึ้นเมื่อมีอย่างน้อย 2 เธรด และ 2 ทรัพยากรขึ้นไป

วิธีป้องกัน Deadlock

  • หลีกเลี่ยง Nested Locks: Deadlock เกิดจากให้ lock หลายเธรด หลีกเลี่ยงการให้ lock หลายตัวหากมีให้อยู่แล้ว
  • หลีกเลี่ยง Unnecessary Locks: ล็อคเฉพาะสมาชิกที่จำเป็น ล็อคไม่จำเป็นนำไปสู่ deadlock
  • ใช้ Thread.join(): Deadlock เกิดเมื่อเธรดรออีกตัวจบ ใช้ Thread.join() พร้อมระบุเวลาสูงสุดที่ควรใช้

ตัวอย่าง

public class DeadlockTest {
    public static void main(String[] args) throws InterruptedException {
        Object obj1 = new Object();
        Object obj2 = new Object();
        Object obj3 = new Object();
        Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
        Thread t2 = new Thread(new SyncThread(obj2, obj3), "t2");
        t1.start();
        Thread.sleep(2000);
        t2.start();
        Thread.sleep(2000);
    }
}

class SyncThread implements Runnable {
    private Object obj1;
    private Object obj2;

    public SyncThread(Object o1, Object o2){
        this.obj1 = o1;
        this.obj2 = o2;
    }

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        System.out.println(name + " acquiring lock on " + obj1);
        synchronized (obj1) {
            System.out.println(name + " acquired lock on " + obj1);
            work();
        }
        System.out.println(name + " released lock on " + obj1);
        System.out.println(name + " acquiring lock on " + obj2);
        synchronized (obj2) {
            System.out.println(name + " acquired lock on " + obj2);
            work();
        }
        System.out.println(name + " released lock on " + obj2);
        System.out.println(name + " finished execution.");
    }

    private void work() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
}

ผลลัพธ์

t1 acquiring lock on java.lang.Object@917d8d4 t1 acquired lock on java.lang.Object@917d8d4 t2 acquiring lock on java.lang.Object@5c4b42fb t2 acquired lock on java.lang.Object@5c4b42fb t1 released lock on java.lang.Object@917d8d4 t1 acquiring lock on java.lang.Object@5c4b42fb t1 acquired lock on java.lang.Object@5c4b42fb t2 released lock on java.lang.Object@5c4b42fb t2 acquiring lock on java.lang.Object@528cb702 t2 acquired lock on java.lang.Object@528cb702 t1 released lock on java.lang.Object@5c4b42fb t2 released lock on java.lang.Object@528cb702 t1 finished execution. t2 finished execution.