了解可重入锁

1.基本概念:

        可重入锁(Reentrant Lock),又称递归锁(Recursive Lock),是一种在多线程编程中使用的锁机制。它允许同一个线程在持有锁的情况下再次获取它,而不会引起死锁。这在处理递归方法或需要重复进入同步代码块的场景下非常有用。

2.特点:

        (1).可重入性:如果一个线程已经获得了锁,再次请求该锁时不会被阻塞,而是允许其成功获取锁并进入同步代码块。这意味着同一个线程可以多次进入锁保护的代码块。

        (2).计数器机制:可重入锁内部通常维护一个计数器,记录当前线程获取锁的次数。每次锁被获取时,计数器加一;每次锁被释放时,计数器减一。当计数器归零时,锁才真正被释放。

        (3).公平性选项:许多可重入锁实现允许设置“公平”策略,按请求锁的顺序(FIFO)分配锁。非公平锁通常会更高效,因为它减少了上下文切换的次数,但可能导致线程饥饿。

3. 与普通锁的区别:

  • 普通锁(如 Java 的 synchronized:一个线程获得锁后,其他线程尝试获取同一个锁时会被阻塞,即使是同一个线程也不能再次进入同步代码块。
  • 可重入锁:同一个线程可以多次获得同一把锁,不会阻塞自己,但其他线程仍会被阻塞。

4.可重入锁适用于以下场景:

  • 递归方法调用:一个持有锁的方法调用另一个持有相同锁的方法,如果没有可重入锁,线程会被阻塞。
  • 分段操作需要持有锁:在复杂的多线程环境中,一个方法可能会分多个步骤操作共享资源,这时可重入锁能防止出现死锁情况。

5.示例:

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();

    public void outerMethod() {
        lock.lock();  // 获取锁
        try {
            System.out.println("Outer method executing...");
            innerMethod();  // 调用内层方法
        } finally {
            lock.unlock();  // 释放锁
        }
    }

    public void innerMethod() {
        lock.lock();  // 线程可以再次获取同一把锁
        try {
            System.out.println("Inner method executing...");
        } finally {
            lock.unlock();  // 释放锁
        }
    }

    public static void main(String[] args) {
        ReentrantLockExample example = new ReentrantLockExample();
        example.outerMethod();
    }
}

        在这个示例中,outerMethod()innerMethod() 都在同一线程中调用,同一线程可以多次获取同一把锁。

6.优缺点:

        6.1优点

        (1).解决递归调用或同一线程需要多次进入同步代码块的问题。

        (2).可以实现公平锁,避免线程饥饿。

        6.1缺点

        (1).相比于 synchronized,使用更复杂且容易出错(需要显式获取和释放锁)。

        (2).使用不当可能导致死锁。

7.可重入锁的主要解决的问题是:

  • 递归调用中的死锁问题:允许同一个线程多次获取同一把锁。
  • 在多个方法之间共享锁的场景:保持线程在不同方法调用中对同一资源的控制。
  • 更灵活的锁管理:支持可中断的锁获取和公平锁策略。

你可能感兴趣的:(java,开发语言)