美文网首页
Java实现死锁的几种方式

Java实现死锁的几种方式

作者: lkmc2 | 来源:发表于2018-01-27 13:35 被阅读220次

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态,这些永远在互相等待的进程称为死锁进程。

实现死锁的方式有如下几种:
方式一(在synchronized的方法中调用对方对象的方法)

package deadlock;

/**
 * Created by lkmc2 on 2018/1/27.
 */
class MyThread1 implements Runnable {
    private String objName;
    private MyThread1 lockObj; //用来持有对方的对象

    public MyThread1(String objName) {
        this.objName = objName;
    }

    public void setLockObj(MyThread1 lockObj) {
        this.lockObj = lockObj;
    }

    public synchronized void intoB() {
        String currentThread = Thread.currentThread().getName();
        System.out.printf("线程%s进入intoB,objName=%s\n", currentThread, objName);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException x) {
        }
        System.out.printf("线程%s尝试进入intoA,objName=%s\n", currentThread, objName);
        lockObj.intoA();
        System.out.printf("线程%s离开intoB(),objName=%s\n", currentThread, objName);
    }

    public synchronized void intoA() {
        String currentThread = Thread.currentThread().getName();
        System.out.printf("线程%s进入intoA,objName=%s\n", currentThread, objName);
        try {
            Thread.sleep(500);
        } catch (InterruptedException x) {
        }
        System.out.printf("线程%s尝试进入intoB,objName=%s\n", currentThread, objName);
        lockObj.intoB();
        System.out.printf("线程%s离开intoA(),objName=%s\n", currentThread, objName);
    }

    @Override
    public void run() {
        if (objName.equals("A")) {
            intoA();
        } else {
            intoB();
        }
    }
}

public class Test1 {

    public static void main(String[] args) throws InterruptedException {
        final MyThread1 obj1 = new MyThread1("A");
        final MyThread1 obj2 = new MyThread1("B");

        obj1.setLockObj(obj2); //持有对方的对象
        obj2.setLockObj(obj1);

        Thread threadA = new Thread(obj1, "threadA");
        threadA.start();

        Thread.sleep(200);

        Thread threadB = new Thread(obj2, "threadB");
        threadB.start();
    }
}
方式1运行结果.png

方式二(在synchronized代码块中锁定不同的对象)

package deadlock;

/**
 * Created by lkmc2 on 2018/1/27.
 */
class MyThread2 implements Runnable {
    private final String[] lock = {"A", "B"};

    private void intoA(String threadName, int index) {
        System.out.println("线程" + threadName + "尝试进入intoA");
        synchronized (lock[index]) {
            System.out.println("线程" + threadName + "进入intoA");
            sleep(200);
            intoB(threadName, 1);
        }
    }

    private void intoB(String threadName, int index) {
        System.out.println("线程" + threadName + "尝试进入intoB");
        synchronized (lock[index]) {
            System.out.println("线程" + threadName + "进入intoB");
            sleep(200);
            intoA(threadName, 0);
        }
    }

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        if ("threadA".equals(threadName)) {
            intoA(threadName, 0);
        } else {
            intoB(threadName, 1);
        }
    }

    public void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class Test2 {
    public static void main(String[] args) throws InterruptedException {
        MyThread2 thread1 = new MyThread2();

        new Thread(thread1, "threadA").start();

        Thread.sleep(5);

        new Thread(thread1, "threadB").start();
    }
}
方式2运行结果.png

方式三(嵌套两层synchronized锁并相互锁定所需的对象)

package deadlock;

/**
 * Created by lkmc2 on 2018/1/27.
 */

class LockA implements Runnable {

    @Override
    public void run() {
        System.out.println("LockA开始执行……");
        while (true) {
            synchronized (Test3.obj1) {
                System.out.println("LockA锁住obj1……");
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Test3.obj2) {
                    System.out.println("LockA锁住obj2……");
                }
                System.out.println("LockA释放obj2……");
            }
            System.out.println("LockA释放obj1……");
        }
    }
}

class LockB implements Runnable {

    @Override
    public void run() {
        System.out.println("LockB开始执行……");
        while (true) {
            synchronized (Test3.obj2) {
                System.out.println("LockB锁住obj1……");
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Test3.obj1) {
                    System.out.println("LockB锁住obj2……");
                }
                System.out.println("LockB释放obj2……");
            }
            System.out.println("LockB释放obj1……");
        }
    }
}

public class Test3 {
    public static final byte[] obj1 = new byte[0];
    public static final byte[] obj2 = new byte[0];

    public static void main(String[] args) {
        LockA lockA = new LockA();
        LockB lockB = new LockB();

        new Thread(lockA).start();
        new Thread(lockB).start();
    }
}
方式3运行结果.png

相关文章

网友评论

      本文标题:Java实现死锁的几种方式

      本文链接:https://www.haomeiwen.com/subject/psenaxtx.html