线程死锁
2020-11-30 本文已影响0人
何几时
死锁定义
多个线程各自占用共享资源,都在等待对方线程释放资源来继续运行,某一个同步块内若同时拥有两个以上对象的锁时,就会发生死锁现象
死锁避免方法
产生死锁的四个必要条件
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
- 不剥夺条件:进程已获得的资源,在未使用时,不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的等待资源关系
化妆例子
// 死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {
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 Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice; // 选择
String girlName; // 使用化妆品的人
public Makeup(int choice, String girlName) {
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
// 化妆
makeup();
}
// 化妆,互相持有对方的锁,就是需要拿到对方的资源
private void makeup() {
if (choice==0) {
synchronized (lipstick) { // 获得口号的锁
System.out.println(this.girlName + "获得口红的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (mirror) {
System.out.println(this.girlName + "获得镜子的锁");
}
}
}else {
synchronized (mirror) { // 获得口号的锁
System.out.println(this.girlName + "获得镜子的锁");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lipstick) {
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}
}
改进版本(把同步块内的另一个同步块拿出来)
package demo04_synchronized;
// 死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock1_0 {
public static void main(String[] args) {
Makeup01 g1 = new Makeup01(0, "灰姑凉");
Makeup01 g2 = new Makeup01(1, "白雪公主");
g1.start();
g2.start();
}
}
// 口红
class Lipstick01{
}
// 镜子
class Mirror01{
}
class Makeup01 extends Thread{
static demo04_synchronized.Lipstick lipstick = new demo04_synchronized.Lipstick();
static demo04_synchronized.Mirror mirror = new demo04_synchronized.Mirror();
int choice; // 选择
String girlName; // 使用化妆品的人
public Makeup01(int choice, String girlName) {
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
// 化妆
makeup();
}
// 化妆,互相持有对方的锁,就是需要拿到对方的资源
private void makeup() {
if (choice==0) {
synchronized (lipstick) { // 获得口号的锁
System.out.println(this.girlName + "获得口红的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (mirror) {
System.out.println(this.girlName + "获得镜子的锁");
}
}else {
synchronized (mirror) { // 获得口号的锁
System.out.println(this.girlName + "获得镜子的锁");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (lipstick) {
System.out.println(this.girlName + "获得口红的锁");
}
}
}
}