开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
死锁
死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。
通俗来讲就是,假如有两个人。一个是「灰姑娘」一个是「白雪公主」,灰姑娘手上拿着口红,白雪公主拿着镜子。突然灰姑娘想要镜子为自己画口红,白雪公主想要对着镜子为自己画口红。这不就大眼对小眼了,卡住了。口红和镜子只有一个,正常来说这时候就只能有一方让出自己的东西(正常人思维)。可是程序都是死死拿着自己手上的东西不可退让,因此产生了悲剧~也就是死锁。。。。
//死锁:多个线程互相抱着对方需要的资源同时又请求对方的资源,然后形成僵持
public class TestDeadLock {
public static void main(String[] args) {
MakeUp g1 = new MakeUp(0, "灰姑凉");
MakeUp g2 = new MakeUp(1, "白雪公主");
g1.start();
g2.start();
}
}
//口红
class Lipstick {
}
//镜子
class Mirror {
}
class MakeUp extends Thread {
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice; //选择
String girlName;//使用化妆品的人
MakeUp(int choice, String girlName) {
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeup() throws InterruptedException {
if (choice == 0) {
synchronized (lipstick) {//获得口红的锁
System.out.println(this.girlName + "获得口红的锁");
Thread.sleep(1000);
}
synchronized (mirror) {//一秒后想要镜子
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(1000);
}
} else {
synchronized (mirror) {//获得镜子的锁
System.out.println(this.girlName + "获得镜子的锁");
Thread.sleep(1000);
}
synchronized (lipstick) {//一秒后想要口红的锁
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}
编码
public class DeadLockDemo {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new MyThread(lockA, lockB), "T1").start();
new Thread(new MyThread(lockB, lockA), "T2").start();
}
}
class MyThread implements Runnable {
private String lockA;
private String lockB;
public MyThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA) {
System.out.println(Thread.currentThread().getName() + "lock:" + lockA + "=>get" + lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB) {
System.out.println(Thread.currentThread().getName() + "lock:" + lockB + "=>get" + lockA);
}
}
}
}
定位分析
中终端使用jps命令查看进程号定位。
得到进程号6705
再使用jstack 进程号命令查看具体信息。
可以看到引发死锁的具体原因!