编写一个死锁实例

Java编程语言的三大特点,注意不是面向对象语言的三大特性(封装,继承,多态)。

  1. 异常处理
  2. 垃圾回收
  3. 多线程
    本文聊聊如何实现一个死锁,在Java里我们可以给对象加锁通过sychronized关键字。
    死锁的条件是相互请求对方所占用的资源。我们可以让两个线程分别占用一个对象,并请求另一个线程所占用的对象。这样达到死锁的目的。
class Ob implements Runnable {
    // 定义两个对象
    Object o1 = new Object();
    Object o2 = new Object();
    // 状态码,控制线程锁哪个对象
    int status;
    Ob(int status) {
        this.status = status;
    }
    public int getStatus() {
        return status;
    }
    public void setStatus(int status) {
        this.status = status;
    }

    public void run() {
        if(status == 1) {
            // 3给o1加锁
            synchronized (o1) {
                Thread currentThread = Thread.currentThread();
                System.out.println(currentThread.getName() + " locked -- >> o1");
                System.out.println(currentThread.getName() + " sleep 1s ...");
                try {
                    // 4锁住对象1,然后休眠,等待o2被锁
                    Thread.sleep(550); // 这里时间 > 500 + thread2启动线程,否则thread2还来不及锁住o2
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(currentThread.getName() + " gets up");
                // 这个时候请求 o2
                synchronized (o2) {
                    System.out.println(currentThread.getName() + "want to lock o2");
                }
            }
        }
        if(status == 2) {
            // 7锁住o2
            synchronized (o2) {
                Thread currentThread = Thread.currentThread();
                System.out.println(currentThread.getName() + " locked -- >> o2");
                // 8 o1 被锁,发生死锁
                synchronized (o1) {
                    System.out.println(currentThread.getName() + "want to lock o1");
                }
            }
        }
        System.out.println("death locked ...this println don't execute forever..");
    }
}

主线程这样去调用:

Ob ob = new Ob(1);
        Thread thread = new Thread(ob,"thread ---- 1");
        thread.start();
        // 1如果不让主线程暂停,则在启动thread之前,已经修改了ob的status = 2,只会去锁对象2了,并且执行两次
        try {
            // 2休眠500ms,让thread启动,否则还还没启动ob.status 就被改变了
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 5thread.start这个时候的状态肯定锁住了o1
        ob.setStatus(2);
        Thread thread2 = new Thread(ob, "thread ----- 2");
        thread2.start(); // 6这个时候请求线程去锁o2

你可能感兴趣的:(java)