Java线程活锁的实现与死锁等的区别
作者:小张frog
活锁是一种递归情况,其中两个或更多线程将继续重复特定的代码逻辑,本文主要介绍了Java线程活锁的实现与死锁等的区别,具有一定的参考价值,感兴趣的可以了解一下
1、什么是活锁
活锁是指,线程没有发生阻塞,但依然执行不下去的情况。
2、活锁的例子
如果两个线程互相改变对方的结束条件,就可能导致双方谁也无法结束。
比如这个程序:
public class TestLiveLock { static volatile int count = 10; static final Object lock = new Object(); public static void main(String[] args) { new Thread(() -> { // 期望减到 0 退出循环 while (count > 0) { sleep(0.2); count--; log.debug("count: {}", count); } }, "t1").start(); new Thread(() -> { // 期望超过 20 退出循环 while (count < 20) { sleep(0.2); count++; log.debug("count: {}", count); } }, "t2").start(); } }
相当于一个抽水一个注水,水池永远不会空或者满
用生活举例看Java多线程活跃性问题【死锁、饥饿、活锁】
死锁:吃饭问题,5个人每人只有一双筷子,只有让另外一个人分享他自己的筷子给自己,自己才能吃到饭。若存在这样的情况,若每个人都不把自己的筷子借给别人用餐,每个人都抓着自己手中的筷子不放,那么每个人都吃不上饭饿死了。也就是说A线程拥有B线程所需的资源,B线程也有A线程所需资源,但两者都不把资源分享出来,最后需求达不到,最后饿死。
饥饿问题:学校饭堂排队打饭,但有些人无秩序插队,那么插队的人拥有了更高的优先级,更可能打到饭吃,也可能他买上了饭也不离开,导致后面的人无法打饭。最后那些守规矩的人(优先级很低的人),就被饿死了。
引起饥饿问题的一些因素:
- 高优先级吞噬所有低优先级的CPU时间片
- 线程被永久堵塞在一个等待进入同步块的状态
- 等待的线程永远不被唤醒来
如果尽量避免饥饿问题:
设置合理的优先级,使用锁来代替synchronized
活锁:到达终点有两条路(记作1号路和2号路),有一对冤家A和B两人同时走了1号路,在途中相遇,他们俩看见了对方,于是都转身离开,A走了2号路,B也走了2号路,在行走的过程中,两人又再见碰面,于是又转身离开。后来A、B两人又同时走了1号路又再次碰面,就这样反反复复...这就是活锁问题
到此这篇关于Java线程活锁的实现与死锁等的区别的文章就介绍到这了,更多相关Java线程活锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!