描述一下线程安全活跃态问题和竞态条件?

本文探讨了Java多线程中的线程安全问题,包括活锁、饥饿和死锁的定义、常见情况及解决方案。活锁是线程反复尝试但无法执行的情况,解决方案可包括随机等待或时间轮策略。饥饿发生在线程无法获取所需资源,可通过公平分配资源或避免无限循环来缓解。死锁是线程间互相等待锁的状态,解决方法涉及加锁顺序、加锁时限和死锁检测。此外,文章还提及了竞态条件,即多个线程对同一资源的访问冲突。

前言

本文分享一道关于Java多线程的面试题,希望能够帮到大家~

一、线程安全活跃态问题

指的是某个线程因为某件事情得不到执行情况,主要分为活锁、饥饿、死锁三种

1、活锁

线程没有阻塞,但一直重复执行某个操作,并且失败重试

1.1 一些情况

  • 在消息队列中,消费者没有正确ack消息,并且执行过程中报错了,消息会被重复执行,一直失败并重试
  • for循环忘记break
  • 递归忘记写结束条件

1.2 解决方案

让线程等待一个随机时间,可以按照时间轮去重试,到达一定时间退出重试

2、 饥饿

线程因为无法访问所需资源而一直在等待

2.1 两种情况

  • 线程优先级问题,不合理分配,导致部分线程始终无法获得CPU资源而一直无法执行,例如:读写锁,读优先,会造成饥饿,写一直在等
  • 一些线程在临界区无限循坏等待资源,让其他线程一直拿不到锁进去临界区,进入了饥饿状态

2.2 解决方案

  • 保证资源充足(但很多场景下,资源稀缺无法解决)
  • 公平分配资源(使用公平锁,FIFO策略)
  • 避免持有锁的线程长时间执行

3、死锁

多个线程互相等待对方释放锁的过程

解决

  • 加锁顺序,按照一定的顺序加锁
  • 加锁时限,超过时限则放弃对该锁的请求,并释放自己占有的锁
  • 死锁检测

二、竞态条件

多个线程同时访问相同资源,如果对资源的访问顺序敏感,就称存在竞态条件

常见的情况:

  • 先检查后执行:检查值的状态,根据这个状态去更新,但期间可能被其它线程修改,导致执行结果出现各种问题
  • 延迟初始化,单例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Forlan

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值