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

死锁

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

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

活锁

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

饥饿

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

无锁

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

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

java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?的更多相关文章

  1. Java多线程中的死锁

    Java多线程中的死锁 死锁产生的原因 线程死锁是指由两个以上的线程互相持有对方所需要的资源,导致线程处于等待状态,无法往前执行. 当线程进入对象的synchronized代码块时,便占有了资源,直到 ...

  2. java多线程中的死锁情况读书笔记

    多线程中的死锁 在前面的分析中,我们知道一个对象可以用Synchronized方法或者其他的加锁形式来防止别的任务在互斥还没有释放的时候就访问这个对象. 试想一下这样的情况:某个任务在等待另一个任务, ...

  3. Java的死锁及解决思路(延伸: 活锁,饥饿,无锁)

    死锁: A线程持有 锁1,接下来要获取锁2:与此同时,B线程持有锁2,要获取锁1.两个线程都在等对方释放自己需要的锁,这时两方会永远等待下去,就形成了死锁. 死锁的四个必要条件: 1.互斥:资源(锁) ...

  4. Java多线程中的死锁问题

    Java程序基本都要涉及到多线程,而在多线程环境中不可避免的要遇到线程死锁的问题.Java不像数据库那么能够检测到死锁,然后进行处理,Java中的死锁问题,只能通过程序员自己写代码时避免引入死锁的可能 ...

  5. Java 多线程中的死锁概述

    死锁 死锁的定义 发生在并发中 当两个线程(或更多)线程(或线程)相互持有对方所需要的资源,又不主动释放,导致所有线程都无法继续执行,是程序陷入无尽的阻塞,这就是死锁. 如果多个线程之间的依赖关系是环 ...

  6. Java多线程——线程的死锁

    Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...

  7. java多线程中的三种特性

    java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...

  8. java 多线程中的wait方法的详解

    java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...

  9. java多线程中并发集合和同步集合有哪些?区别是什么?

    java多线程中并发集合和同步集合有哪些? hashmap 是非同步的,故在多线程中是线程不安全的,不过也可以使用 同步类来进行包装: 包装类Collections.synchronizedMap() ...

随机推荐

  1. LeetCode 795. Number of Subarrays with Bounded Maximum

    问题链接 LeetCode 795 题目解析 给定一个数组A,左右范围L.R.求子数组的数量,要求:子数组最大值在L.R之间. 解题思路 子数组必须连续,利用最大值R对数组进行分段,设定变量 left ...

  2. 半年的iOS代码生活

    半年的iOS代码生活 在高考大军中拼杀过,也在大学校园中荒芜过,曾经低迷消沉,也常满怀壮志…… 但是最多的还是被称为小伙子以及自称为iOS工程师!博主就是这种喜闻乐见的这类人,实习一年后在2015年的 ...

  3. Python基础部分的疑惑解析(2)

    变量: 变量名由 字母.数字.下划线构成,数字不能做为开头 不能用关键字:另外一些内置的方法也别用 推荐使用下划线命名间两个单词user_id 变量在最后底层处理的时候没什么意义,但是在命名的时候有利 ...

  4. 【算法笔记】B1052 卖个萌

    题目链接:https://pintia.cn/problem-sets/994805260223102976/problems/994805273883951104 #include <math ...

  5. PowerDesigner16 生成的备注脚本,在sql server 2008 中报“对象名 'sysproperties' 无效”的错误的解决办法

    主要是在建模时我们对表.列增加了些说明注释,而Sql2005之后系统表sysproperties已废弃删除而改用sys.extended_properties所致. 1.修改Table TableCo ...

  6. spring boot快速入门 9: 单元测试

    进行单元测试: service第一种方式: 第一步:在指定service中创建一个方法进行测试 /** * 通过ID查询一个女生的信息 * @param id * @return */ public ...

  7. DotNetCore跨平台~autofac属性的自动注入

    回到目录 在使用autofac这个DI工具时,我们一般使用的是构造方法注入,而dotnetcore的标准框架里也集成了构造方法注入,而属性注入在一些场景下,表现的更为灵活,像java的spring框架 ...

  8. Django时间与时区设置问题

    在Django的配置文件settings.py中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE和USE_TZ 如果USE_TZ设置为True时,Django会使用系统默认设置的时区,即 ...

  9. C#(winform)设置窗口置顶

    只要设置窗体的TopMost属性即可: registerForm.TopMost = true;

  10. Eclipse: User Operation is waiting for “Building Workspace”

    这个情况可能有多个原因导致,比如,非正常关闭eclipse,时钟不匹配等等,可能解决的方法有: 1. 删除<workspace_folder>/.metadata/.lock文件 2. e ...