1.什么是死锁
- 主线程拥有a对象的锁,并试图获取b对象的锁;
- 副线程拥有b对象的锁,并试图获取a对象的锁;
- 大家谁都不释放,OK,场面僵住了,死锁出现了;
2.Demo
/**
* @version V1.0
* @ClassName:DeadLockTest
* @Description: 死锁测试
* @author:Daniel
* @date:2020/11/28 下午9:37
*/
public class DeadLockTest implements Runnable{
A a = new A();
B b = new B();
public void init() {
Thread.currentThread().setName("主线程");
// 调用a对象的foo()方法
a.foo(b);
System.out.println("进入了主线程后");
}
@Override
public void run() {
Thread.currentThread().setName("副线程");
// 调用b对象的bar方法
b.bar(a);
System.out.println("进入了副线程之后");
}
public static void main(String[] args) {
DeadLockTest d1 = new DeadLockTest();
new Thread(d1).start();
d1.init();
}
}
class A {
public synchronized void foo(B b) {
System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入了A实例的foo()方法");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程名:" + Thread.currentThread().getName() + " 试图进入B实例的last()方法");
b.last();
}
public synchronized void last() {
System.out.println("当前线程名: " + Thread.currentThread().getName() + " 进入了A实例的 last() 方法 ");
}
}
class B {
public synchronized void bar(A a) {
System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入了B实例的bar()方法");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程名:" + Thread.currentThread().getName() + " 试图进入A实例的last()方法");
a.last();
}
public synchronized void last() {
System.out.println("当前线程名: " + Thread.currentThread().getName() + " 进入了B实例的 last() 方法 ");
}
}
运行结果:
3. 解释
- 程序中有两个线程执行,副线程的线程执行体是DeadLock类run( )方法,主线程的线程执行体是DeadLock的main( )方法(主线程调用了init()方法)。
- 其中run()方法中让B对象调用bar()方法,而init( )方法让A对象调用foo( )方法。
- 结果显示init( )方法先执行,调用了A对象的foo( )方法,进入foo( )方法前,该线程对A对象加锁,执行到sleep( )时,主线程暂停200ms;CPU切换到执行另一个线程。让B对象执行bar( )方法,所以看到副线程开始执行B实例的bar()方法,进入bar( ) 方法之前,该线程对B对象加锁,当执行到sleep(),副线程也暂停200ms
- 接下来,主线程会先醒过来,继续向下执行,执行last( )方法之前,必须先对B对象加锁,但此时副线程正保持着B对象的锁,所以主线程阻塞;
- 接下来,副线程醒过来,向下执行,执行last( )方法之前必须先对A对象加锁,但此时主线程没有释放A对象的锁;
- 至此,就出现了主线程保持着A对象的锁,等待对B对象加锁,而副线程保持着B对象的锁,等待对A对象加锁,两个线程相互等待对方先释放,就出现了死锁。