死锁、活锁、饥饿锁、无锁

2024-02-17 06:30
文章标签 死锁 无锁 饥饿 活锁

本文主要是介绍死锁、活锁、饥饿锁、无锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

死锁、活锁、饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了。

死锁

死锁是多线程中最差的一种情况,多个线程相互占用对方的资源的锁,而又相互等对方释放锁,此时若无外力干预,这些线程则一直处理阻塞的假死状态,形成死锁。

举个例子,A同学抢了B同学的钢笔,B同学抢了A同学的书,两个人都相互占用对方的东西,都在让对方先还给自己自己再还,这样一直争执下去等待对方还而又得不到解决,老师知道此事后就让他们相互还给对方,这样在外力的干预下他们才解决,当然这只是个例子没有老师他们也能很好解决,计算机不像人如果发现这种情况没有外力干预还是会一直阻塞下去的。

死锁产生条件

  • 互斥条件:所谓互斥就是进程在某一时间内独占资源。
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

死锁解决办法

  • 如果并发查询多个表,约定访问顺序。
  • 在同一个事务中,尽可能做到一次锁定获取所需要的资源。
  • 对于容易产生死锁的业务场景,尝试升级锁颗粒度,使用表级锁。
  • 采用分布式事务锁或者使用乐观锁。

活锁

多线程中出现了相互谦让,都主动将资源释放给别的线程使用,这样资源在多个线程之间跳动而又得不到执行,形成活锁。

活锁这个概念大家应该很少有人听说或理解它的概念,而在多线程中这确实存在。活锁恰恰与死锁相反,死锁是大家都拿不到资源都占用着对方的资源,而活锁是拿到资源却又相互释放不执行。当多线程中出现了相互谦让,都主动将资源释放给别的线程使用,这样这个资源在多个线程之间跳动而又得不到执行,这就是活锁。

饥饿

一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。多线程中优先级高的会优先执行,并且抢占优先级低的资源,导致优先级低的线程无法得到执行。

我们知道多线程执行中有线程优先级这个东西,优先级高的线程能够插队并优先执行,这样如果优先级高的线程一直抢占优先级低线程的资源,导致低优先级线程无法得到执行,这就是饥饿。当然还有一种饥饿的情况,一个线程一直占着一个资源不放而导致其他线程得不到执行,与死锁不同的是饥饿在以后一段时间内还是能够得到执行的,如那个占用资源的线程结束了并释放了资源。

与死锁不同的是,饥饿锁在一段时间内,优先级低的线程最终还是会执行的,比如高优先级的线程执行完之后释放了资源。

无锁

无锁,即没有对资源进行锁定,即所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。

无锁典型的特点就是一个修改操作在一个循环内进行,线程会不断的尝试修改共享资源,如果没有冲突就修改成功并退出否则就会继续下一次循环尝试。所以,如果有多个线程修改同一个值必定会有一个线程能修改成功,而其他修改失败的线程会不断重试直到修改成功。之前的文章我介绍过JDK的CAS原理及应用即是无锁的实现。

可以看出,无锁是一种非常良好的设计,它不会出现线程出现的跳跃性问题,锁使用不当肯定会出现系统性能问题,虽然无锁无法全面代替有锁,但无锁在某些场合下是非常高效的。


Kotlin开发者社区

专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。


http://www.taodudu.cc/news/show-8461900.html

相关文章:

  • CPU饥饿与线程饥饿
  • 死锁活锁饥饿
  • Stable Diffusion插件Recolor实现黑白照片上色
  • 黑白照片修复上色怎么弄?我来教你几个方法
  • 各位同志今天更新公众号文章了
  • 似曾相识的智能秤
  • 《自己动手做智能机器人》——1.2 机电一体化产品
  • 智能家居世界的资本热力图
  • 没有技术合伙人和外部投资,照样一年内在硬件创业领域拼下千万营业额
  • 双十一,智能硬件喜忧参半
  • 【Vds、Vod、Vdssat、亚阈值区】
  • 【其他】阿里云视频点播 vod - 客户端上传视频文件到阿里云点播
  • VOD: 视频共享点播服务实现
  • 8月份第一个Python任务,港股 美股交易 选股 量化
  • R插值评价
  • SenseChat
  • Linux|奇怪的知识| 不常用但非常有用的diff命令
  • 剑指offer——整数中1出现的次数(7)Python实现(**********)
  • C语言——求0-100000内所有的水仙花数
  • 随机生成10000个在区间1~10万之间的整数,然后找出最大的10个数字。
  • 打印10000以内的Fibonacci数
  • 传说中,只要学会这五步!就可以成为万中无一的前端工程师
  • 万中选一,北京升哲科技荣获首个物联网行业 IDEA 金奖
  • Maven万中无一的配置教程!
  • 只要学会这五步!就可以成为万中无一的前端工程师
  • 函数万中挑三的方法
  • springboot二手车交易平台 计算机毕设源码58477
  • 武汉市最大的二手车市场
  • 动手学习深度学习8-二手车交易kaggle竞赛理论篇
  • 二手车鉴定评估系统工程日志
  • 这篇关于死锁、活锁、饥饿锁、无锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/716939

    相关文章

    【Linux修行路】线程安全和死锁

    目录 ⛳️推荐 一、线程安全 1.1 常见的线程不安全情况 1.2 常见的线程安全情况 1.3 常见的不可重入情况 1.4 常见可重入的情况 1.5 可重入与线程安全的联系 1.6 可重入与线程安全的区别 二、死锁 2.1 死锁的四个必要条件 2.2 如何避免产生死锁? ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大

    模拟线程死锁——Thread学习笔记

    记录一下之前写过的一段模拟死锁的代码: /*** 模拟死锁** @author lixiang* @date 2018年10月12日 - 9:51* @history 2018年10月12日 - 9:51 lixiang create.*/public class HoldLockDemo {private static Object[] lock = new Object[10];priv

    【编程底层思考】如何检测和避免线程死锁

    一、什么是线程死锁? 线程死锁发生在多个线程因为争夺资源而相互阻塞,导致程序无法正常结束的情况。例如,线程A持有资源2并等待资源1,线程B持有资源1并等待资源2,这样就形成了死锁。 二、如何检测死锁? 使用jmap、jstack等命令行工具查看JVM的线程栈和堆内存情况,jstack可以显示死锁信息。使用VisualVM、JConsole等图形化工具进行排查。例如,JConsole可以连接到

    C++11 Thread线程池、死锁、并发

    一、线程与进程         进程:运行中的程序         线程:进程中的小进程 二、线程库的使用         包含头文件#include<thread> 2.1 thread函数         具体代码: void show(string str) {cout << "This is my word : " << str << endl;}int main() {t

    C++ 的死锁问题的发生和避免

    C/C++程序中产生死锁的原因很多,本文大致归纳了下面几类,分别做分析。 1.单线程/进程多次加锁导致死锁 单线程导致死锁的情况一般是由于调用了引起阻塞的函数,比如(copy_from_user()、copy_to_ser()、和kmalloc()),阻塞后进行系统调度,调度的过程中有可能又调用了之前获取锁的函数,这样必然导致死锁。 还有一种就是自旋锁函数在没有释放锁马上又进行申请同一个自旋

    阅读笔记(五)多线程无锁的C++实现《Lock-Free Data Structures》

    1. 前言   本文介绍使用C++实现多线程中无锁算法的实现和优化过程。 2. 无锁&CAS   在多线程程序中,加锁是一种必要的手段,由于保证数据操作的正确性(原子性)。但是这也在很多时候带来了性能的极度下降,因为所有共享数据的操作均需要加锁,有些时候会严重影响性能,比如当读键盘或者一些较慢的I/O操作时,锁会延误了其他线程的操作。更糟糕的是,不当操作可能会带来死锁。   首先介绍最经典

    yt零售系统订单死锁原因

    知识前提: InnoDB引擎在加锁的时候,只有通过索引进行检索的时候才会使用行级锁,否则会使用表级锁。 场景: 在订单服务中,开起事务,对同一张表,先更新(无索引),再新增,发生死锁。 原因: 同一线程,更新事务未提交,因为无索引导致了表锁,再新增的时候当前线程等待更新释放锁,会把当前线程挂起来,而锁正是被自己占用,该线程又被挂起而没机会释放锁。 解决方法: 更新的时候在检索列创建索

    Oracle:杀死死锁进程

    Oracle:杀死死锁进程 1. 模拟死锁现象 利用PL/SQL Developer工具可以很容易模拟死锁现象。用同一个数据库的同一个用户登录2个PL/SQL Developer。 首先,在其中一个PL/SQL Developer随便对数据库的表执行一个更新操作,不要提交,状态为“待提交” 然后,在另一个PL/SQL Developer执行同样的操作,此时这个操作会等待前面的事务提交之后

    Android 线程死锁的案例

    模拟java 线程死锁 ExecutorService executorService = Executors.newFixedThreadPool(2);Object lockA =new Object();Object lockB =new Object();executorService.submit(new Runnable() {@Overridepublic void

    java线程死锁例子及解决方法

    Java线程死锁是由于有些资源彼此交叉取用,就有可能造成死结. 如1线程中 取得A对象的锁定后又要取得B对象的锁定.但是同时2线程中取得B对象的锁定后又要取得A对象的锁定.这两个线程同时发生时就会造成,1线程拿到A对象锁定后等待B对象的锁定.2线程拿到B对象锁定后等待A对象锁定.这样就会进入没有停止的等待中. 线程死锁的一个简单例子: package deadLockThread;publi