Java中的线程死锁解读

 更新时间:2024年01月18日 09:02:15   作者:小白不很白  
这篇文章主要介绍了Java中的线程死锁解读,死锁就是指两个或两个以上的线程在抢占资源时,造成相互等待的现象,称为死锁,在没有外力的情况下是会一直等待无法执行下去,需要的朋友可以参考下

Java线程死锁

线程死锁就是指两个或两个以上的线程在抢占资源时,造成相互等待的现象,称为死锁。在没有外力的情况下是会一直等待无法执行下去的。

在这里插入图片描述

1. 死锁产生必须具备以下条件

  • 互斥条件:指线程获取到的资源进行排它性使用,即当获取该资源锁的时候其他线程是获取不到该锁资源的。
  • 请求并持有:当线程持有资源时,又要请求其他锁资源,但是其他所资源被其他线程所占有。但是等待的时候并不会释放自己所占有的资源。
  • 不可剥夺条件:自己获取的所资源当没有使用完的时候不释放锁资源。
  • 环路等待条件:环路等待就是就是线程需求形成一个环形链。比如有【T0…Tn】个线程,T0需要T1占有的锁资源,T1需要T2的锁资源…Tn需要T0的锁资源。

例:

public class User {
    private static Object objectA = new Object();
    private static Object objectB = new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (objectA){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("111111111111");
                    synchronized (objectB){
                        System.out.println("222222222222");
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (objectB){
                    Thread.sleep(1000);
                    System.out.println("3333333333333");
                    synchronized (objectA){
                        System.out.println("44444444444444");
                    }
                }
            }
        }).start();
    }
}

分析:首先objectA、objectB都是互斥资源。当第一个线程获取到objectA资源时,还需要请求objectB资源,当第一个线程获取到objectB资源时,还需要请求objectA资源。这样就造成了请求并持有条件。第一个和第二个获取的资源当他们没有执行结束时都不可被剥夺,这样就形成资源不可剥夺条件。第一个线程需要objectB资源,造成在等待 持有objectA资源,第二个线程需要objectA资源,造成在等待objectA的时候 持有objectB资源,这就形成了环路等待条件,所以就造成了死锁。

2. 如何避免死锁

避免死锁只需要把四种中的一个给破坏掉就可以了。但是我们只能破回掉,环路等待条件请求并持有条件

造成死锁的条件其实和线程请求资源的顺序有很大的关系,使用资源的有序性原则就能很大可能的避免死锁。

例:

public class User {
    private static Object objectA = new Object();
    private static Object objectB = new Object();
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (objectA){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("111111111111");
                    synchronized (objectB){
                        System.out.println("222222222222");
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (objectA){
                    System.out.println("3333333333333");
                    synchronized (objectB){
                        System.out.println("44444444444444");
                    }
                }
            }
        }).start();
    }
}

如上代码就是把这两个线程申请的资源顺序给调成一样的了,这样就可以避免死锁,当第一个线程请求完毕,另一个线程才能占有资源,这样就不会造成线程的死锁了。

到此这篇关于Java中的线程死锁解读的文章就介绍到这了,更多相关Java线程死锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringCloud基于RestTemplate微服务项目案例解析

    SpringCloud基于RestTemplate微服务项目案例解析

    这篇文章主要介绍了SpringCloud基于RestTemplate微服务项目案例,在写SpringCloud搭建微服务之前,先搭建一个不通过springcloud只通过SpringBoot和Mybatis进行模块之间通讯,通过一个案例给大家详细说明,需要的朋友可以参考下
    2022-05-05
  • Java聊天室之实现运行服务器与等待客户端连接

    Java聊天室之实现运行服务器与等待客户端连接

    这篇文章主要为大家详细介绍了Java简易聊天室之实现运行服务器程序与等待客户端程序连接功能,文中的示例代码讲解详细,需要的可以了解一下
    2022-10-10
  • 如何用java给文件加密的简单实现

    如何用java给文件加密的简单实现

    文件加密,简单来说就是把文件读取出来,把读取出来的字节码数组进行遍历,把每一个码值和一个秘钥(随便一个数)进行异或运算,将运算后的结果全部写入到文件里,这篇文章主要介绍了如何用java给文件加密的简单实现,需要的朋友可以参考下
    2023-12-12
  • 基于Java Callable接口实现线程代码实例

    基于Java Callable接口实现线程代码实例

    这篇文章主要介绍了基于Java Callable接口实现线程代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • listview点击无效的处理方法(推荐)

    listview点击无效的处理方法(推荐)

    下面小编就为大家带来一篇listview点击无效的处理方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • IDEA中添加xml配置文件时,显示file问题

    IDEA中添加xml配置文件时,显示file问题

    这篇文章主要介绍了IDEA中添加xml配置文件时,显示file问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • MyBatis-Plus数据权限插件的简单使用

    MyBatis-Plus数据权限插件的简单使用

    在MyBatis-Plus中,通过DataPermissionInterceptor插件实现数据权限控制,首先需要创建自定义注解和处理类,利用JSQLParser库动态修改SQL,实现按角色权限过滤数据,配置类中注册拦截器,确保只有授权用户能访问指定数据,感兴趣的可以了解一下
    2024-10-10
  • JDBC用IDEA连接SQLServer数据库的超实用教程

    JDBC用IDEA连接SQLServer数据库的超实用教程

    JDBC是Java连接数据库的一种接口,它由各个数据库厂商为开发者提供的接口,要使用它需要到相应厂商下载对应的jar包,下面这篇文章主要给大家介绍了关于JDBC用IDEA连接SQLServer数据库的超实用教程,需要的朋友可以参考下
    2023-05-05
  • Java中常用数据类型的输入输出详解

    Java中常用数据类型的输入输出详解

    本文主要介绍了Java中几个常用的数据类型是如何输入和输出的,例如:Char型、int型、double型、数组、字符串等,对我们学习java有一定的帮助,感兴趣的小伙伴可以跟随小编一起学习学习
    2021-12-12
  • Spring Boot多模块(双后端服务)整合Smart-Doc实战指南

    Spring Boot多模块(双后端服务)整合Smart-Doc实战指南

    Smart-Doc虽然是静态源码分析工具,但完全可以优雅地应对这种多可运行模块结构,只要理解它的生成机制,就很容易实现多模块的整合,本文介绍Spring Boot多模块(双后端服务)整合Smart-Doc实战指南,感兴趣的朋友跟随小编一起看看吧
    2026-03-03

最新评论