Java死锁

简介: Java死锁

死锁

多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情景,某一个代码块同时拥有两个或者两个以上的锁时,就会发生死锁的问题

死锁就是多个线程互相持有对方所需要的资源,形成僵持,谁也拿不到

代码实现死锁


package com.wyh.thread;
import org.omg.PortableServer.THREAD_POLICY_ID;
import java.awt.*;
/**
 * @program: Thread
 * @description: 死锁测试
 * @author: 魏一鹤
 * @createDate: 2022-01-16 18:34
 **/
//死锁:多个线程互相持有对方所需要的资源,形成僵持,谁也拿不到
public class DeadLock {
public static void main(String[] args){
//实例化两个女生去拿资源
         MakeUp  makeUp1=new MakeUp(0,"灰姑娘");
         MakeUp  makeUp2=new MakeUp(1,"白雪公主");
//开启执行方法
        makeUp1.start();
        makeUp2.start();
    }
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class MakeUp extends Thread{
//需要使用到的资源只有一份,用static只有一份
    static   Lipstick lipstick=new Lipstick();
static   Mirror mirror=new Mirror();
//选择
    int choose;
//使用化妆品的人
    String name;
//有参数的构造方法
    MakeUp(int choose,String name){
this.choose = choose;
this.name = name;
    }
//继承Thread重写run方法
    @Override
public void run() {
//化妆
        try {
            makeUp();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
//化妆方法,互相持有对方的锁,就是拿到对方的资源
    private void makeUp() throws InterruptedException {
if(choose==0){
//获得口红的锁
            synchronized (lipstick) {
                System.out.println(this.name+"获得口红的锁");
//获得之后阻塞1s
                Thread.sleep(1000);
//1s后想获得镜子
                synchronized (mirror) {
                    System.out.println(this.name+"获得镜子的锁");
                }
            }
        }else{
//获得口红的锁
            synchronized (mirror) {
                System.out.println(this.name+"获得镜子的锁");
//获得之后阻塞1s
                Thread.sleep(2000);
//2s后想获得口红 上面是一秒这里改为两秒 保证可以获取到资源
                synchronized (lipstick) {
                    System.out.println(this.name+"获得口红的锁");
                }
            }
        }
    }
}


解决死锁,把synchronized代码块拿出来放到外面,不同时获得多个资源


package com.wyh.thread;
import org.omg.PortableServer.THREAD_POLICY_ID;
import java.awt.*;
/**
 * @program: Thread
 * @description: 死锁测试
 * @author: 魏一鹤
 * @createDate: 2022-01-16 18:34
 **/
//死锁:多个线程互相持有对方所需要的资源,形成僵持,谁也拿不到
public class DeadLock {
public static void main(String[] args){
//实例化两个女生去拿资源
         MakeUp  makeUp1=new MakeUp(0,"灰姑娘");
         MakeUp  makeUp2=new MakeUp(1,"白雪公主");
//开启执行方法
        makeUp1.start();
        makeUp2.start();
    }
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
//化妆
class MakeUp extends Thread{
//需要使用到的资源只有一份,用static只有一份
    static   Lipstick lipstick=new Lipstick();
static   Mirror mirror=new Mirror();
//选择
    int choose;
//使用化妆品的人
    String name;
//有参数的构造方法
    MakeUp(int choose,String name){
this.choose = choose;
this.name = name;
    }
//继承Thread重写run方法
    @Override
public void run() {
//化妆
        try {
            makeUp();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
//化妆方法,互相持有对方的锁,就是拿到对方的资源
    private void makeUp() throws InterruptedException {
if(choose==0){
//获得口红的锁
            synchronized (lipstick) {
                System.out.println(this.name+"获得口红的锁");
//获得之后阻塞1s
                Thread.sleep(1000);
            }
//1s后想获得镜子
            synchronized (mirror) {
                System.out.println(this.name+"获得镜子的锁");
            }
        }else{
//获得口红的锁
            synchronized (mirror) {
                System.out.println(this.name+"获得镜子的锁");
//获得之后 阻塞1s
                Thread.sleep(2000);
            }
//2s后想获得口红 上面是一秒这里改为两秒 保证可以获取到资源
            synchronized (lipstick) {
                System.out.println(this.name+"获得口红的锁");
            }
        }
    }
}


产生死锁的四个必要条件

  1. 互斥条件:一个资源每次只能被一个进行使用
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对已经获得资源保持不放
  3. 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

如何解决死锁

一种是用synchronized,一种是用Lock显式锁实现

也可以进行时间限制,在规定的时间内,如果可以获取到锁就得到,获取不到就算了

目录
相关文章
|
3月前
|
监控 算法 安全
Java并发编程案例分析:死锁的检测与解决
Java并发编程案例分析:死锁的检测与解决
38 2
|
3月前
|
Java
如何避免 Java 中的死锁?
【8月更文挑战第22天】
30 4
|
3月前
|
存储 SQL 关系型数据库
深入MySQL锁机制:原理、死锁解决及Java防范技巧
深入MySQL锁机制:原理、死锁解决及Java防范技巧
|
3月前
|
安全 算法 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(下)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
77 6
|
3月前
|
存储 安全 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(中)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
86 5
|
3月前
|
存储 安全 Java
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)(上)
17 Java多线程(线程创建+线程状态+线程安全+死锁+线程池+Lock接口+线程安全集合)
84 3
|
3月前
|
Java
Java多线程-死锁的出现和解决
死锁是指多线程程序中,两个或以上的线程在运行时因争夺资源而造成的一种僵局。每个线程都在等待其中一个线程释放资源,但由于所有线程都被阻塞,故无法继续执行,导致程序停滞。例如,两个线程各持有一把钥匙(资源),却都需要对方的钥匙才能继续,结果双方都无法前进。这种情况常因不当使用`synchronized`关键字引起,该关键字用于同步线程对特定对象的访问,确保同一时刻只有一个线程可执行特定代码块。要避免死锁,需确保不同时满足互斥、不剥夺、请求保持及循环等待四个条件。
|
5月前
|
Java
在Java中,死锁是指两个或多个线程互相等待对方释放资源,从而导致所有线程都无法继续执行的情况。
【6月更文挑战第24天】在Java并发中,死锁是多线程互相等待资源导致的僵局。避免死锁的关键策略包括:防止锁嵌套,设定固定的加锁顺序,使用`tryLock`带超时,避免无限等待,减少锁的持有时间,利用高级同步工具如`java.util.concurrent`,以及实施死锁检测和恢复机制。通过这些方法,可以提升程序的并发安全性。
43 1
|
5月前
|
Java
死锁是线程间争夺资源造成的无限等待现象,Java示例展示了两个线程各自持有资源并等待对方释放,导致死锁。`
【6月更文挑战第20天】死锁是线程间争夺资源造成的无限等待现象,Java示例展示了两个线程各自持有资源并等待对方释放,导致死锁。`volatile`保证变量的可见性和部分原子性,确保多线程环境中值的即时更新。与`synchronized`相比,`volatile`作用于单个变量,不保证原子操作,同步范围有限,但开销较小。`synchronized`提供更全面的内存语义,保证原子性和可见性,适用于复杂并发控制。
42 3
|
4月前
|
Java API
Java面试题:解释死锁的概念,给出避免死锁的常见策略。你能给我一个具体的例子吗?
Java面试题:解释死锁的概念,给出避免死锁的常见策略。你能给我一个具体的例子吗?
43 0
下一篇
无影云桌面