Java多线程中的死锁
Java多线程中的死锁
死锁产生的原因
线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行。
当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源。在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁。
死锁产生的必要条件
- 互斥条件:进程对于锁分配的资源具有排他性,即一个资源只能被一个线程所拥有,直到该线程被释放
- 请求和保持条件:一个进程因为请求被占用资源而发生阻塞,对已获得的资源保持不放
- 不可剥夺条件:任何一个资源在没被该线程程释放之前,任何线程都没有办法剥夺占用
- 循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞
手写一个死锁
public class DeadLock {
static Object a = new Object();
static Object b = new Object();
public static void main(String[] args) {
new Thread(()->{
synchronized (a){
System.out.println(Thread.currentThread().getName()+"占用锁A,获取锁B");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b){
System.out.println(Thread.currentThread().getName()+"获取锁B");
}
}
},"A").start();
new Thread(()->{
synchronized (b){
System.out.println(Thread.currentThread().getName()+"占用锁A,获取锁B");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a){
System.out.println(Thread.currentThread().getName()+"获取锁B");
}
}
},"B").start();
}
}
验证死锁
Jstack命令
jps -l
显示当前系统的java进程情况及进程id,类似于linux中的ps -ef查看进程号
jstack 进程号。
jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息
解决死锁
产生死锁需要四个条件,那么,只要这四个条件中至少有一个条件得不到满足,就不可能发生死锁了。其中互斥条件是不可以破坏的,它是线程安全的基础
一、破坏请求和保持条件
- 如果需要多个资源,则一次性全部申请,无法申请,则等待。
- 在逻辑允许情况下,在使用完一个资源后,则释放当前资源。
二、破坏不可剥夺条件
当需要多个资源,只获得了部分资源,无法获得其他资源时,则释放所有资源;
三、破坏循环等待条件
给所有资源进行线性排序标号,在程序请求资源时,按顺序获取和使用资源。
解决死锁的方法有很多,只是举了几个例子
Java多线程中的死锁的更多相关文章
- java多线程中的死锁情况读书笔记
多线程中的死锁 在前面的分析中,我们知道一个对象可以用Synchronized方法或者其他的加锁形式来防止别的任务在互斥还没有释放的时候就访问这个对象. 试想一下这样的情况:某个任务在等待另一个任务, ...
- Java多线程中的死锁问题
Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...
- java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
死锁.活锁.饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了. 死锁 死锁是多线程中最差的一种情况,多个线程相互占用对方的资源的锁,而又 ...
- Java 多线程中的死锁概述
死锁 死锁的定义 发生在并发中 当两个线程(或更多)线程(或线程)相互持有对方所需要的资源,又不主动释放,导致所有线程都无法继续执行,是程序陷入无尽的阻塞,这就是死锁. 如果多个线程之间的依赖关系是环 ...
- Java多线程——线程的死锁
Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- java多线程中并发集合和同步集合有哪些?区别是什么?
java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...
- java多线程中最佳的实践方案是什么?
java多线程中最佳的实践方案是什么? 给你的线程起个有意义的名字.这样可以方便找bug或追踪.OrderProcessor, QuoteProcessor or TradeProcessor 这种名 ...
随机推荐
- C# Dapper基本三层架构使用 (三、BLL)
BLL层介绍 业务逻辑层用于做一些有效性验证的工作,以更好的保证程序运行的健壮性.如完成数据添加.修改和查询业务等:不允许指定的文本框中输入空字符串,数据格式是否正确以及数据类型验证:用户权限的合法性 ...
- 定时器及PWM
1 定时器 1.1 定时器分类 对于STM32来说,定时器可分为基本定时器.通用定时器.高级定时器三类,后者包括前者的全部功能.以stm32f1系列为例,TIM6和TIM7为基本定时器,TIM2~TI ...
- Shell系列(19)- 正则表达式
正则表达式与通配符 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep,awk,sed等命令可以支持正则表达式. 通配符用来匹配符号条件的文件名,通配符是完全匹配.ls,find,c ...
- Shell系列(13)- read
前言 作用是往脚本中传递参数,之前文章的位置参数变量也有此功能,但是只适用于脚本的作者,为什么?第三方用户不知道这个脚本要传递哪些参数,这些参数分别是什么.本篇随笔read就可以实现上述功能,别且该命 ...
- sonar扫描java项目报错
安装maven 配置path 验证maven,看到以下信息证明已经成功 扫描项目 扫描以下项目: kf-buss-nhgip-smartoffice-business-thirdparty 项目的配置 ...
- 最推荐的抓包工具charles
Charles是一个HTTP代理服务器,HTTP监视器,反转代理服务器,当浏览器连接Charles的代理访问互联网时,Charles可以监控浏览器发送和接收的所有数据.它允许一个开发者查看所有连接互联 ...
- SQL连接查询的执行顺序?
sql和mysql执行顺序,发现内部机制是一样的.最大区别是在别名的引用上. 一.sql执行顺序 (1)from (2)on (3)join (4)where (5)group by(开始使用sele ...
- 『Python』优雅的记录日志——loguru
1. 安装 pip install loguru 2. 初识 from loguru import logger logger.debug("This is a debug..." ...
- 一凡老师亲录视频,Python从零基础到高级进阶带你飞
如需Q群交流 群:893694563 不定时更新2-3节视频 零基础学生请点击 Python基础入门视频 如果你刚初入测试行业 如果你刚转入到测试行业 如果你想学习Python,学习自动化,搭建自动化 ...
- WPF进阶技巧和实战03-控件(5-列表、树、网格04)
ListView控件 ListView继承自简单的没有特色的ListBox,增加了对基于列显示的支持,并增加了快速切换视图或显示模式的能力,而不需要重新绑定数据以重新构建列表. ListView类继承 ...