死锁概念
多个线程因竞争同一个资源,而造成的相互等待的状态,如果不加干预,将会一直持续下去,这就是死锁。
例子:嵌套同步代码
public class Test {
public Object mLock1 = new Object();
public Object mLock2 = new Object();
public void test1() {
synchronized (mLock1) {
//do something
synchronized (mLock2) {
//do something
}
}
}
public void test2() {
synchronized (mLock2) {
//do something
synchronized (mLock1) {
//do something
}
}
}
}
具体例子:能运行的,通俗易懂的
package interview.learnjava21;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) {
MarkUp markUp0 = new MarkUp("迪丽热巴",0);
MarkUp markUp1 = new MarkUp("杨幂",1);
markUp0.start();
markUp1.start();
}
}
// 口红类
class LipStick {
}
// 镜子类
class Mirror {
}
// 化妆类
class MarkUp extends Thread {
private int choice;
private String userName;
private static LipStick lipStick = new LipStick();
private static Mirror mirror = new Mirror();
MarkUp(String userName, int choice) {
this.userName = userName;
this.choice = choice;
}
@Override
public void run() {
try {
markUP();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void markUP() throws InterruptedException {
// 如果选择0方式化妆
if (choice == 0) {
// 同步代码块的锁,在同步代码块有效
synchronized (lipStick) {
System.out.println(userName + "拿到了口红");
// 拿到口红后再拿镜子
TimeUnit.SECONDS.sleep(1);
// 程序执行此处会停止 -----------------这里死锁----------------------->
synchronized (mirror) {
System.out.println(userName + "拿到了镜子");
}
}
}
// 如果选择1方式化妆
if (choice == 1) {
// 同步代码块的锁,在同步代码块有效
synchronized (mirror) {
System.out.println(userName + "拿到了镜子");
// 拿到镜子后再拿口红
TimeUnit.SECONDS.sleep(1);
// 程序执行此处会停止 -----------------这里死锁----------------------->
synchronized (lipStick) {
System.out.println(userName + "拿到了口红");
}
}
}
}
}
如果不让他形成死锁,就需要修改同步代码块,不能让同补代码块嵌套,这样就可以避免死锁。