没了解死锁怎么能行?进来看看,一文带你拿下死锁产生的原因、死锁的解决方案。

🌈🌈🌈今天给大家分享的是死锁产生的原因,以及如何解决死锁问题。

清风的CSDN博客

🛩️🛩️🛩️希望我的文章能对你有所帮助,有不足的地方还请各位看官多多指教,大家一起学习交流!

✈️✈️✈️动动你们发财的小手,点点关注点点赞!在此谢过啦!哈哈哈!😛😛😛

目录

一、死锁是什么 

 二、哲学家就餐问题

三、如何避免死锁 

3.1 死锁产生的四个必要条件 

3.2 破除循环等待 

四、关于多线程的一些问题

4.1 谈谈 volatile关键字的用法? 

4.2 Java多线程是如何实现数据共享的? 

4.3 Java创建线程池的接口是,参数 LinkedBlockingQueue 的作用

4.4  Java线程共有几种状态?状态之间怎么切换的?

4.5 在多线程下,如果对一个数进行叠加,该怎么做? 

4.6 Thread和Runnable的区别和联系?

4.7 多次start一个线程会怎么样 

4.8 有synchronized两个方法,两个线程分别同时用这个方法,会发生什么?  

4.9 进程和线程的区别 


一、死锁是什么 

死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
举个例子理解死锁
滑稽老哥和女神一起去饺子馆吃饺子,吃饺子需要酱油和醋。
滑稽老哥抄起了酱油瓶, 女神抄起了醋瓶。
滑稽: 你先把醋瓶给我, 我用完了就把酱油瓶给你。
女神: 你先把酱油瓶给我, 我用完了就把醋瓶给你。
如果这俩人彼此之间互不相让, 就构成了死锁.
酱油和醋相当于是两把锁, 这两个人就是两个线程。 

 为了进一步阐述死锁的形成, 很多资料上也会谈论到 "哲学家就餐问题"。

 二、哲学家就餐问题

  • 有个桌子, 围着一圈哲学家, 桌子中间放着一盘意大利面。每个哲学家两两之间, 放着一根筷子。

每个哲学家只做两件事: 思考人生或者吃面条。思考人生的时候就会放下筷子,吃面条就会拿起左
右两边的筷子(先拿起左边, 再拿起右边)。

 如果哲学家发现筷子拿不起来了(被别人占用了), 就会阻塞等待。

  • [关键点] 假设同一时刻, 五个哲学家同时拿起左手边的筷子, 然后再尝试拿右手的筷子, 就会发现右手的筷子都被占用了。由于哲学家们互不相让, 这个时候就形成了 死锁

死锁是一种严重的 BUG!! 导致一个程序的线程 "卡死", 无法正常工作!  

三、如何避免死锁 

3.1 死锁产生的四个必要条件 

  • 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用。
  • 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  • 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  • 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

其中最容易破坏的就是 "循环等待"。 

3.2 破除循环等待 

最常用的一种死锁阻止技术就是 锁排序。 假设有 N 个线程尝试获取 M 把锁 , 就可以针对 M 把锁进行编号 (1, 2, 3...M)。

 N 个线程尝试获取锁的时候, 都按照固定的按编号由小到大顺序来获取锁. 这样就可以避免环路等待。

可能产生环路等待的代码:

两个线程对于加锁的顺序没有约定, 就容易产生环路等待。

Object lock1 = new Object();
Object lock2 = new Object();
Thread t1 = new Thread() {
    @Override
    public void run() {
        synchronized (lock1) {
            synchronized (lock2) {
                // do something...
           }
       }
   }
};
t1.start();
Thread t2 = new Thread() {
    @Override
    public void run() {
        synchronized (lock2) {
            synchronized (lock1) {
                // do something...
           }
       }
   }
};
t2.start();

 约定好先获取 lock1, 再获取 lock2 , 就不会环路等待。

Object lock1 = new Object();
Object lock2 = new Object();
Thread t1 = new Thread() {
    @Override
    public void run() {
        synchronized (lock1) {
            synchronized (lock2) {
                // do something...
           }
       }
   }
};
t1.start();
Thread t2 = new Thread() {
    @Override
    public void run() {
        synchronized (lock1) {
            synchronized (lock2) {
                // do something...
           }
       }
   }
};
t2.start();
}

四、关于多线程的一些问题

4.1 谈谈 volatile关键字的用法? 

volatile 能够保证内存可见性,强制从主内存中读取数据。此时如果有其他线程修改被 volatile 修饰的变量, 可以第一时间读取到最新的值。

4.2 Java多线程是如何实现数据共享的? 

JVM 把内存分成了这几个区域:
方法区, 堆区, 栈区, 程序计数器。
其中堆区这个内存区域是多个线程之间共享的。
只要把某个数据放到堆内存中, 就可以让多个线程都能访问到。

4.3 Java创建线程池的接口是,参数 LinkedBlockingQueue 的作用

创建线程池主要有两种方式:
  • 通过 Executors 工厂类创建,创建方式比较简单, 但是定制能力有限。
  • 通过 ThreadPoolExecutor 创建,创建方式比较复杂, 但是定制能力强。
LinkedBlockingQueue 表示线程池的任务队列,用户通过 submit / execute 向这个任务队列中添加任务, 再由线程池中的工作线程来执行任务。

4.4  Java线程共有几种状态?状态之间怎么切换的?

  • NEW: 安排了工作, 还未开始行动,新创建的线程, 还没有调用 start 方法时处在这个状态。
  • RUNNABLE: 可工作的。又可以分成正在工作中和即将开始工作,调用 start 方法之后, 并正在CPU 上运行/在即将准备运行的状态。
  • BLOCKED: 使用 synchronized 的时候, 如果锁被其他线程占用, 就会阻塞等待, 从而进入该状态。
  • WAITING: 调用 wait 方法会进入该状态。
  • TIMED_WAITING: 调用 sleep 方法或者 wait(超时时间) 会进入该状态。
  • TERMINATED: 工作完成了,当线程 run 方法执行完毕后, 会处于这个状态。

4.5 在多线程下,如果对一个数进行叠加,该怎么做? 

  • 使用 synchronized / ReentrantLock 加锁
  • 使用 AtomInteger 原子操作

4.6 ThreadRunnable的区别和联系?

  • Thread 类描述了一个线程。
  • Runnable 描述了一个任务。
  • 在创建线程的时候需要指定线程完成的任务, 可以直接重写 Thread 的 run 方法, 也可以使用Runnable 来描述这个任务。

4.7 多次start一个线程会怎么样 

  • 第一次调用 start 可以成功调用
  • 后续再调用 start 会抛出 java.lang.IllegalThreadStateException 异常

4.8 synchronized两个方法,两个线程分别同时用这个方法,会发生什么?  

synchronized 加在非静态方法上, 相当于针对当前对象加锁。
如果这两个方法属于同一个实例:
线程1 能够获取到锁, 并执行方法。线程2会阻塞等待, 直到线程1 执行完毕, 释放锁, 线程2 获取到锁之后才能执行方法内容。
如果这两个方法属于不同实例:
两者能并发执行, 互不干扰

4.9 进程和线程的区别 

  • 进程是包含线程的,每个进程至少有一个线程存在,即主线程。
  • 进程和进程之间不共享内存空间,同一个进程的线程之间共享同一个内存空间。
  • 进程是系统分配资源的最小单位,线程是系统调度的最小单位。

🌈🌈🌈好啦,今天的分享就到这里!

🛩️🛩️🛩️希望各位看官读完文章后,能够有所提升。

🎉🎉🎉创作不易,还希望各位大佬支持一下!

✈️✈️✈️点赞,你的认可是我创作的动力!

⭐⭐⭐收藏,你的青睐是我努力的方向!

✏️✏️✏️评论:你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/212963.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hdoop学习笔记(HDP)-Part.09 安装OpenLDAP

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

[蓝桥杯 2019 省 B] 特别数的和-C语言的解法

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。 请问,在 1 到 n 中,所有这样的数的和是多少&…

JavaScript编程基础 – For循环

JavaScript编程基础 – For循环 JavaScript Programming Essentials – For Loop By JacksonML 循环可以多次执行代码块,而不用反复重写相同的语句。这无疑对提升代码质量、减少错误大有脾益。本文将简要介绍for循环的几种案例,希望对读者有所帮助。 …

笔记本电脑关闭触摸板

大部分人用笔记本 其实都是外接的鼠标 那么在打游戏 以及一些切图操作中 为了防止碰到触摸板导致误操作 我们就可以将他关掉 我们可以按快捷键 Win i 或者 点击桌面 此电脑/我的电脑/此计算机 打开设置界面 如果 左侧菜单中有设备 那么 直接点击设备 然后左侧菜单就会有 触摸…

阿里系列-淘宝接口抓取及相关问题

阿里系-淘宝接口抓取 一、安装charlse抓包工具 官方下载地址 安装证书 二、安装xposed hook框架 Xponsed简介 具体安装步骤 三、安装模块 关闭阿里系ssl验证 开启http模式 支持支付宝、淘宝、淘宝直播各个接口抓取 四、效果如下 接下去一段时间更新阿里系相关接口 文章目录 一、…

TA-Lib学习研究笔记(二)——Overlap Studies上

TA-Lib学习研究笔记(二)——Overlap Studies 1. Overlap Studies 指标 [BBANDS, DEMA, EMA, HT_TRENDLINE, KAMA, MA, MAMA, MAVP, MIDPOINT, MIDPRICE, SAR, SAREXT, SMA, T3, TEMA, TRIMA, WMA]2.数据准备 get_data函数参数(代码&#x…

文心一言 VS 讯飞星火 VS chatgpt (148)-- 算法导论12.2 3题

三、用go语言,写出过程 TREE-PREDECESSOR 的伪代码。 文心一言: 以下是使用Go语言编写的TREE-PREDECESSOR函数的伪代码: func TREE-PREDECESSOR(node) { if node.parent ! nil { return node.parent } // 如果节点是根节点&#xff0c…

有点迷糊class和初始化参数的用法了

翻阅手册https://www.runoob.com/python3/python3-class.html Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。 如果你以前没有接触过面向对象的编程语言&…

洛谷 P1998 阶乘之和 C++代码

前言 今天我们来做洛谷上的一道题目。 网址:[NOIP1998 普及组] 阶乘之和 - 洛谷 西江月夜行黄沙道中 【宋】 辛弃疾 明月别枝惊鹊,清风半夜鸣蝉。稻花香里说丰年,听取WA声一片。 七八个星天外,两三点雨山前。旧时茅店社林边&…

『亚马逊云科技产品测评』活动征文|基于亚马逊云EC2搭建OA系统

授权声明:本篇文章授权活动官方亚马逊云科技文章转发、改写权,包括不限于在 Developer Centre, 知乎,自媒体平台,第三方开发者媒体等亚马逊云科技官方渠道 亚马逊EC2云服务器(Elastic Compute Cloud)是亚马…

Verilog 入门(九)(建模实例)

文章目录 建模的不同方式条件操作建模通用移位寄存器状态机建模Moore 有限状态机建模Mealy 型有限状态机建模 建模的不同方式 分别使用数据流方式、行为方式和结构方式对下图所示的电路进行建模: 数据流方式:使用连续赋值语句对电路建模 module Save_M…

【ArcGIS Pro微课1000例】0043:深度学习--框架库安装

ArcGIS Pro 中的所有深度学习地理处理工具都要求安装支持的深度学习框架库。 文章目录 深度学习框架库下载深度学习框架库安装注意事项深度学习框架库下载 由于是python开发,可以采用安装包与Pip两种方式安装,本文讲解采用安装包安装。 点击深度学习框架库下载,打开网站,…

二叉树链式结构的实现和二叉树的遍历以及判断完全二叉树

二叉树的实现 定义结构体 我们首先定义一个结构来存放二叉树的节点 结构体里分别存放左子节点和右子节点以及节点存放的数据 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left;struct BinaryTreeNode* right; }BTNode;…

【数电笔记】20-有约束的逻辑函数化简

目录 说明: 约束项和约束条件 1. 引例 1.1 引例中的约束项 1.2 引例中的约束条件 利用约束项 / 约束条件化简逻辑函数 1. 例1 2. 例2 3. 例3 4. 例4 说明: 笔记配套视频来源:B站;本系列笔记并未记录所有章节&#xff0…

HTTPS安全防窃听、防冒充、防篡改三大机制原理

前言 本文内容主要对以下两篇文章内容整理过滤,用最直观的角度了解到HTTPS的保护机制,当然啦,如果想要深入了解HTTPS,本文是远远不够的,可以针对以下第一个链接中的文章拓展板块进行学习,希望大家通过本文能…

css如何设置文本添加下划线

css文本添加下划线 text-decoration: underline;text-decoration相关属性参数 参数描述none默认。定义标准的文本。underline定义文本下的一条线。overline定义文本上的一条线。line-through定义穿过文本下的一条线。blink定义闪烁的文本。inherit规定应该从父元素继承 text-…

人体姿态估计算法

人体姿态估计算法 1 什么是人体姿态估计2 基于经典传统和基于深度学习的方法2.1 基于经典传统的人体姿态估计算法2.2 基于深度学习的人体姿态估计算法OpenPoseAlphaPose (RMPE) 3 算法应用4 Paper 人体姿态估计在现实中的应用场景很丰富,如下 动作捕捉:三…

非常好的简历精选7篇

想要打造一份令人眼前一亮的简历,赢得招聘方的青睐?参考这7篇精选的“非常好的简历”案例!无论是应届毕业生还是职场人士,都能从中借鉴灵感,提升简历质量。让求职之路更加顺畅,轻松斩获心仪职位&#xff01…

跨境独立站和传统外贸的差异

跨境独立站和传统外贸主要在以下几个方面存在区别: 交易形式:传统外贸主要涉及线下交易,买卖双方需要经过面谈、磋商、签订合同等环节。而跨境独立站则主要通过线上平台进行交易,买卖双方可以通过平台发布产品、协商价格、完成支…

linux 内核regulator

问题 在sys文件系统下没有生成cpu 调频的相关节点。 日志对比 [ 3.588745] cpu cpu4: Looking up cpu-supply from device tree [ 3.588753] cpu cpu4: Failed to get reg [ 3.588791] cpu cpu4: Looking up cpu-supply from device tree [ 3.588808] Failed to i…
最新文章