前言
本文分享一道关于Java多线程的面试题,希望能够帮到大家~
一、线程安全活跃态问题
指的是某个线程因为某件事情得不到执行情况,主要分为活锁、饥饿、死锁三种
1、活锁
线程没有阻塞,但一直重复执行某个操作,并且失败重试
1.1 一些情况
- 在消息队列中,消费者没有正确ack消息,并且执行过程中报错了,消息会被重复执行,一直失败并重试
- for循环忘记break
- 递归忘记写结束条件
1.2 解决方案
让线程等待一个随机时间,可以按照时间轮去重试,到达一定时间退出重试
2、 饥饿
线程因为无法访问所需资源而一直在等待
2.1 两种情况
- 线程优先级问题,不合理分配,导致部分线程始终无法获得CPU资源而一直无法执行,例如:读写锁,读优先,会造成饥饿,写一直在等
- 一些线程在临界区无限循坏等待资源,让其他线程一直拿不到锁进去临界区,进入了饥饿状态
2.2 解决方案
- 保证资源充足(但很多场景下,资源稀缺无法解决)
- 公平分配资源(使用公平锁,FIFO策略)
- 避免持有锁的线程长时间执行
3、死锁
多个线程互相等待对方释放锁的过程
解决
- 加锁顺序,按照一定的顺序加锁
- 加锁时限,超过时限则放弃对该锁的请求,并释放自己占有的锁
- 死锁检测
二、竞态条件
多个线程同时访问相同资源,如果对资源的访问顺序敏感,就称存在竞态条件
常见的情况:
- 先检查后执行:检查值的状态,根据这个状态去更新,但期间可能被其它线程修改,导致执行结果出现各种问题
- 延迟初始化,单例
本文探讨了Java多线程中的线程安全问题,包括活锁、饥饿和死锁的定义、常见情况及解决方案。活锁是线程反复尝试但无法执行的情况,解决方案可包括随机等待或时间轮策略。饥饿发生在线程无法获取所需资源,可通过公平分配资源或避免无限循环来缓解。死锁是线程间互相等待锁的状态,解决方法涉及加锁顺序、加锁时限和死锁检测。此外,文章还提及了竞态条件,即多个线程对同一资源的访问冲突。
745

被折叠的 条评论
为什么被折叠?



