Java多线程死锁例子和简单分析

161 阅读1分钟

两个线程等待对方释放同步监视器的时候,就会出现“死锁”情况。

synchronized需要设置一个对象,线程必须要获取这个对象才能执行同步代码块中的代码,否则就不执行同步代码块中的代码。

synchronized(Object obj){   // 需要设置一个对象 
    // 同步代码块
}

下面是例子


对象类,同步代码块需要一个对象,定义两个静态变量,保证每个对象只存在一个。

public class LockCenter {
    public static final Object INSTANCE_A = new Object();
    public static final Object INSTANCE_B = new Object();
}

线程实现类

/**
 *实现Runnable接口 重写run方法 
 */
public class DealLockDemo extends Thread {
    private boolean flag;
    public DealLockDemo(boolean flag){
        this.flag=flag;
    }
    
    @Override
    public void run(){
        // flag作用:保证两个线程走不同的条件语句。
        if (flag) {
            synchronized (LockCenter.INSTANCE_A) {
                // 线程A获取INSTANCE_A对象,运行到此处。
                System.out.println("A->");
                // 线程A运行到此处 有可能INSTANCE_B被线程B给抢占,所以不能往下运行
                // 只有等待线程B释放才可以运行到下面的同步代码块
                synchronized (LockCenter.INSTANCE_B) {
                    System.out.println("A->B执行完成");
                }
            }
        } else {
            synchronized (LockCenter.INSTANCE_B) {
                // 线程B获取INSTANCE_B对象,运行到此处。
                System.out.println("B->");
                // 同理,线程B运行到此处,刚好线程A抢占了INSTANCE_A,线程B也无法继续往下运行
                // 所以线程A和B都在等待对方释放资源,线程A等待线程B释放INSTANCE_B 线程B等待线程A释放INSTANCE_A
                // 两个线程都无法继续往下运行,这就造成了“死锁”
                synchronized (LockCenter.INSTANCE_A) {
                    System.out.println("B->A执行完成");
                }
            }
        }
    }
}

运行

public static void main(String[] args) {
        DealLockDemo A = new DealLockDemo(true);    // 线程A
        DealLockDemo B = new DealLockDemo(false);   // 线程B
        A.start(); 
        b.start(); 
}

运行结果

A->
B->

这就是出现了"死锁"。 System.out.println("B->A执行完成")与System.out.println("A->B执行完成")并没有得到执行。