本文主要是介绍【Java并发】聊聊活锁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
在并发编程中,为了保证数据安全性,所以使用锁机制,syn lock cas 等方式保证,但是也从一定程度降低了性能。而除了这个方面,还引入了锁竞争,比如死锁、活锁。
【Java并发】聊聊死锁
避免死锁:避免线程持有锁并等待锁
产生死锁的根本原因就是两个以上线程持有A锁的前提下,继续等待B锁。那么如果在获取B锁的时候,获取失败,直接释放原有的A锁,也可以打破这个局面。
/*** @author qxlx* @date 2024/1/21 21:07*/
public class DemoLock {private Lock lockA = new ReentrantLock();private Lock lockB = new ReentrantLock();public void f() {for ( ;;) {try {lockA.lock();boolean tryLock = lockB.tryLock();if (tryLock) {try {lockB.lock();// 处理业务逻辑} finally {lockB.unlock(); }}} finally {lockA.unlock();}}}public void g() {for ( ;;) {try {lockB.lock();boolean tryLock = lockA.tryLock();if (tryLock) {try {lockA.lock();// 处理业务逻辑} finally {lockA.unlock();}}} finally {lockB.unlock();}}}}
活锁
上面的代码,其实是存在问题的,极端情况下。线程T1 获取lock1锁的时候,尝试获取lock2锁,但是获取lock2锁失败。线程T1释放lock1锁之前,线程T2持有lock2锁,去获取lock1锁失败。如此,就是我尝试获取了,但是失败,一直获取不到自己想要的锁。也释放自己的锁,让对方获取,但是对方获取不到。互相谦让。
一个直白的案例就是:两个人过独木桥,死锁是 你不让,我也不让。大家僵持。
活锁是:你让,我也让,结果都不过桥。
区别:
死锁是两个线程都会阻塞,不会消耗CPU资源,但是活锁却不是,不断的加锁解锁,尝试获取锁失败,解锁。一直占用CPU资源,从而导致一直执行不下去。
那么如何解决呢?
其实办法非常简单,就是在尝试获取锁失败的时候,sleep一会,保证两个线程不是同步操作就可以。
boolean tryLock = lockB.tryLock(r.nextLong() % 10, TimeUnit.MILLISECONDS);
这篇关于【Java并发】聊聊活锁的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!