JUC之可重入锁

前言

本文主要是【JUC】——JUC之可重入锁的文章,如果有什么需要改进的地方还请大佬指出⛺️

作者简介:大家好,我是听风与他
☁️博客首页:CSDN主页听风与他
每日一句:狠狠沉淀,顶峰相见

目录

    • 前言
    • 可重入锁
    • 文章末尾

可重入锁

  • ReentrantLock,其实是锁的一种,叫做可重入锁,可重入:简单来说,就是同一个线程,可以反复进行加锁操作。

    	public static void main(String[] args) throws InterruptedException {
    		ReentrantLock lock = new ReentrantLock();
    		lock.lock();
    		lock.lock();   //连续加锁2次
    		new Thread(() -> {
    			System.out.println("线程2想要获取锁");
    			lock.lock();
    			System.out.println("线程2成功获取到锁");
    		}).start();
    		lock.unlock();
    		System.out.println("线程1释放了一次锁");
    		TimeUnit.SECONDS.sleep(1);
    		lock.unlock();
    		System.out.println("线程1再次释放了一次锁");  //释放两次后其他线程才能加锁
    	}
    

    输出结果为

    线程1释放了一次锁
    线程2想要获取锁
    线程1再次释放了一次锁
    线程2成功获取到锁
    

可以看到,主线程连续进行了两次加锁操作(此操作是不会被阻塞的),在当前线程持有锁的情况下继续加锁不会被阻塞,并且,加锁几次,就必须要解锁几次,否则此线程依旧持有锁。我们可以使用getHoldCount()方法查看当前线程的加锁次数:

public static void main(String[] args) throws InterruptedException {
		ReentrantLock lock = new ReentrantLock();
		lock.lock();
		lock.lock();
		System.out.println("当前加锁次数:"+lock.getHoldCount()+",是否被锁:"+lock.isLocked());
		TimeUnit.SECONDS.sleep(1);
		lock.unlock();
		System.out.println("当前加锁次数:"+lock.getHoldCount()+",是否被锁:"+lock.isLocked());
		TimeUnit.SECONDS.sleep(1);
		lock.unlock();
		System.out.println("当前加锁次数:"+lock.getHoldCount()+",是否被锁:"+lock.isLocked());
	}

打印结果:

当前加锁次数:2,是否被锁:true
当前加锁次数:1,是否被锁:true
当前加锁次数:0,是否被锁:false
  • 当锁不再被任何线程持有时,值为0,并且通过isLocked()方法查询结果为false。

如果存在线程持有当前的锁,那么其他线程在获取锁时,暂时会进入到等待队列,我们可以通过getQueueLength()方法获取等待中线程数量的预估值。

public static void main(String[] args) throws InterruptedException {
    ReentrantLock lock = new ReentrantLock();
    lock.lock();
    Thread t1 = new Thread(lock::lock), t2 = new Thread(lock::lock);;
    t1.start();
    t2.start();
    TimeUnit.SECONDS.sleep(1);
    System.out.println("当前等待锁释放的线程数:"+lock.getQueueLength());
    System.out.println("线程1是否在等待队列中:"+lock.hasQueuedThread(t1));
    System.out.println("线程2是否在等待队列中:"+lock.hasQueuedThread(t2));
    System.out.println("当前线程是否在等待队列中:"+lock.hasQueuedThread(Thread.currentThread()));
}

文章末尾

在这里插入图片描述

你可能感兴趣的:(java,JUC,锁,可重入锁)