ReentrantLock中lock(),tryLock(),lockInterruptibly()的区别

lock()

两个线程都使用lock获取锁,如果线程A获取到了锁,线程B只能等待,对线程B调用interrupt()方法不能中断线程B的等待过程。

tryLock()

使用lock获取锁,如果线程A获取到了锁,线程A返回true,线程B直接返回false。可以传入时间参数,表示拿不到锁等待一段时间,这段时间内还是拿不到就返回false。

lockInterruptibly()

两个线程都使用lockInterruptibly获取锁,如果线程A获取到了锁,线程B只能等待,对线程B调用interrupt()方法能够中断线程B的等待过程。

案例

如下示例中,t0得到了锁,t1等待。在t1等待时,调用t1.interrupt(),中断t1的等待。

public class ReentrantLockDemo {
 
    private Lock lock = new ReentrantLock();
 
    public void test() {
        String name = Thread.currentThread().getName();
        try {
            System.out.println(name + " 尝试获取锁");
            lock.lockInterruptibly();
            Thread.sleep(1000);
            System.out.println(name + " 得到锁");
        } catch (InterruptedException e) {
            System.out.println(name + " InterruptedException异常");
        } finally {
            try {
                lock.unlock();
                System.out.println(name + " 尝试释放锁");
            } catch (Exception e) {
                System.out.println(name + " : 释放锁失败(未获取锁的线程调用unlock)");
            }
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        ReentrantLockDemo lock = new ReentrantLockDemo();
        Thread t0 = new Thread(
                lock::test
        );
        Thread t1 = new Thread(
                lock::test
        );
        t0.start();
        Thread.sleep(10);
        t1.start();
        Thread.sleep(100);
        // 中断等待中的t1的线程
        t1.interrupt();
    }
}

运行结果

Thread-0 尝试获取锁
Thread-1 尝试获取锁
Thread-1 InterruptedException异常
Thread-1 : 释放锁失败(未获取锁的线程调用unlock)
Thread-0 得到锁
Thread-0 尝试释放锁

如果使用lock()方法获取锁,线程不会被中断。将lock.lockInterruptibly()改为lock.lock()。

运行结果

Thread-0 尝试获取锁
Thread-1 尝试获取锁
Thread-0 得到锁
Thread-0 尝试释放锁
Thread-1 lockInterruptibly的InterruptedException异常
Thread-1 尝试释放锁

从案例中可以看出,使用lockInterruptibly方法时候会出现 释放锁失败(未获取锁的线程调用unlock)的异常,而使用lock方法时不会出现这个异常。

原因

使用lockInterruptibly获取锁时,当它处于等待阶段时直接被中断,没有获取到锁,所以调用unlock会发生异常。而使用lock获取锁时,当它处于等待阶段时,中断不了,等到线程0结束后,线程1得到锁才被中断,所以调用unlock时不会发生异常。

你可能感兴趣的:(Java,java,多线程,并发编程)