Java死锁

死锁:

  官方表达:线程1等待线程2互斥持有的资源,而线程2也在等待线程1互斥持有的资源。两条线程都无法继续执行。

  大白话:两个线程1、2,两个资源one、two,线程1抢占到了资源one,同时等待内嵌的资源two的执行。同理线程2抢占到了资源two,同时等待内嵌的资源one的执行。由于线程2无法放弃所拥有的的资源two的锁,导致线程1无期限等待,同时线程2也无限期等待线程1释放资源one。由此产生“死锁”。

示例代码:(摘抄所得

package com.thread;

public class DeathThreadDemo {

    public static void main(String[] args) {
        DeadLock dt0 = new DeadLock(0);
        DeadLock dt1 = new DeadLock(1);
        new Thread(dt0).start();
        new Thread(dt1).start();
    }
}

class DeadLock implements Runnable {
    private int value;
    private static Object o1 = new Object(), o2 = new Object();

    public DeadLock(int value) {
        this.value = value;
    }

    public void run() {
        if (value == 0) {
            synchronized (o1) {
                try {
                    Thread.sleep(3000);
                    for (int i = 11; i < 20; i++) {
                        System.out.println("o1" + i);
                    }
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (o2) {
                    System.out.println("o2" + value);
                }
            }
        }
        if (value == 1) {
            synchronized (o2) {
                try {
                    Thread.sleep(3000);
                    for (int i = 1; i < 10; i++) {
                        System.out.println("o2" + i);
                    }

                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                synchronized (o1) {
                    System.out.println("o1" + value);
                }
            }
        }
    }
}

注意:

示例中写的很明显,资源互相嵌套,互相牵制,从而导致死锁,实际中,很多Java API内部方法用到了同步锁,这时就要小心了。

例如:

/**
     * Prints a String and then terminate the line.  This method behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>String</code> to be printed.
     */
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }

以上代码是习以为常的 System.out.println(“打印”); 中println() 的源码。用到了同步方法。

上一篇:BZOJ2039: [2009国家集训队]employ人员雇佣


下一篇:@bzoj - 4386@ [POI2015] Wycieczki