ReentrantLock的介绍及其用法

Reentrantlock默认是非公平锁

private static ReentrantLock lock = new ReentrantLock();

若想实现公平锁,只需使用重载构造器,fair参数传入true

private static ReentrantLock lock = new ReentrantLock(true);

公平锁会按照线程请求锁的顺序进行获取,遵循先到先得的原则。而非公平锁则没有这种保证,允许新的线程在旧线程之前获取到锁。在大多数情况下,非公平锁的性能更好,因为它允许新的线程立即获取锁,而不需要等待。

如果是公平锁,会先检查AQS队列中是否存在线程在排队,如果有线程在排队,则当前线程也进行排队
如果是非公平锁,则不会去检查是否有线程在排队,而是直接竞争锁

lock()方法

        Thread t1 = new Thread(() -> {
            lock.lock();
            try {
                System.out.println("Thread 1 acquired the lock");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                System.out.println("Thread 1 released the lock");
            }
        });

lockInterruptibly()方法,线程通过此方法获取锁时,线程在执行任务的过程中允许被打断,释放锁并抛出InterruptedException异常

        Thread t1 = new Thread(() -> {
            try {
                lock.lockInterruptibly();
                try {
                    System.out.println("Thread 1 acquired the lock");
                    Thread.sleep(5000);
                } finally {
                    lock.unlock();
                    System.out.println("Thread 1 released the lock");
                }
            } catch (InterruptedException e) {
                System.out.println("Thread 1 was interrupted while waiting for the lock");
            }
        });

        Thread t2 = new Thread(() -> {
            // 让线程2休眠一段时间后打断线程1
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            t1.interrupt(); // 中断线程1的等待
        });

tryLock()方法,尝试获取锁,获取到锁执行逻辑一,没有获取到锁执行逻辑二

        Thread t1 = new Thread(() -> {
            try {
                if (lock.tryLock(5, TimeUnit.SECONDS)) {
                    try {
                        System.out.println("Thread 1 acquired the lock");
                        Thread.sleep(1000);
                    } finally {
                        lock.unlock();
                        System.out.println("Thread 1 released the lock");
                    }
                } else {
                    System.out.println("Thread 1 failed to acquire the lock");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

anyway,这些获取锁的方法,最后都需要调用unlock()方法释放锁,否则其他线程将无法获取锁,从而导致死锁

posted @ 2023-08-30 16:40  Ashe|||^_^  阅读(71)  评论(0编辑  收藏  举报