一、死锁的理解
- 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
- 线程T1持有锁R1并且申请获得锁R2,而线程T2持有锁R2并且申请获得锁R1,所以线程T1和T2永远被阻塞了。导致了死锁。
- 互斥使用:即当资源被一个线程使用(占有)时,别的线程不能使用。
- 不可抢占:资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
- 请求和保持:即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
- 循环等待:即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
1、代码
package com.xz.thread.t5;
/**
* @description: 死锁示例
* @author: xz
*/
public class Demo {
private Object obj1=new Object();
private Object obj2=new Object();
public void a(){
System.out.println("a方法开始执行=========");
synchronized (obj1){
System.out.println( "a方法锁住 obj1");
try {
Thread.sleep(100); // 此处等待是给b方法能锁住机会
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj2){
System.out.println( "a方法执行hello world");
}
}
}
public void b(){
System.out.println("b方法开始执行=========");
synchronized (obj2){
System.out.println( "b方法锁住 obj2");
try {
Thread.sleep(100); // 此处等待是给a方法能锁住机会
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (obj1){
System.out.println( "b方法执行hello world");
}
}
}
public static void main(String[] args) {
Demo d=new Demo();
new Thread(new Runnable() {
@Override
public void run() {
d.a();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
d.b();
}
}).start();
}
}
2、输出结果 3、结论
- 由第2步输出的结果截图可知,a方法和b方法都没有输出hello world,因此产生了死锁。