【Java并发】聊聊活锁

发布时间:2024年01月21日

在并发编程中,为了保证数据安全性,所以使用锁机制,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);
文章来源:https://blog.csdn.net/jia970426/article/details/135735349
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。