ReentrantLock同步锁,重入锁,独占锁,公平锁

对于 ReentrantLock 有很多的名称:同步锁,重入锁,独占锁,公平锁

白话来讲:理解方式就是公平锁,排着队一个一个的来,谁等的时间最长谁就先执行。非公平锁就是不排队,谁先抢到谁就执行

可重入
  什么是可重入?他的作用是什么?可重入(也有叫重入锁的)就是,当一个持有锁的线程,在释放锁之前,被重复访问或者访问了此锁的其他方法,那么这个线程不需要进行抢占锁,只会被记录重入次数,重入锁的作用就是为了防止死锁现象

独占锁
  独占锁顾名思义, 就是一个线程获得了锁,别的线程就不能获得锁,必须等锁释放了,才能可能获取到锁

公平锁
  什么是公平锁?为啥说 ReentrantLock 自带公平锁机制呢?我们接着往下看!可以点开 ReentrantLock 的源码看下,我们创建的 ReentrantLock 对象完整的应该是这个样子的,ReentrantLock 默认使用的是非公平锁,如果不传参数,默认的是 false,然后看下边第二段 ReentrantLock(boolean fair),意思是传入 true 或者 false ,传入 true 就是开启公平锁机制
 

1、不同线程执行同一个lock(),后执行的那个线程的lock()方法会阻塞

         lock();获取锁。
         如果锁未被另一个线程持有,则获取锁,并立即返回,将锁持有计数设置为1。
         如果当前线程已经持有锁,那么持有计数将增加1,并且该方法立即返回。
         如果锁由另一个线程持有,则当前线程出于线程调度目的而被禁用,并且处于休眠状态,直到获取了锁为止,此时锁持有计数被设置为1。

public class Test1 {
    private static ReentrantLock connectedLock = new ReentrantLock();
    private static Condition connectedCondition = connectedLock.newCondition();

    public static void main(String[] args) throws Exception {
        // 线程1
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                connectedLock.lock();
                System.out.println("-----1");
                Thread.sleep(5000);
                System.out.println("-----2");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("-----3");
            }
        }).start();
        // 线程2
        new Thread(() -> {
            try {
                Thread.sleep(1500);
                connectedLock.lock();
                System.out.println("=====1");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("=====2");
            }
        }).start();
    }
}

执行结果:
-----1
-----2
-----3
=====1
=====2

2、ReentrantLock通过Condition能够更加精细的控制多线程的休眠与唤醒。

ReentrantLock通过Condition能够更加精细的控制多线程的休眠与唤醒。_小百菜的博客-CSDN博客

public class Test2 {
    private static ReentrantLock connectedLock = new ReentrantLock();
    private static Condition connectedCondition = connectedLock.newCondition();

    public static void main(String[] args) throws Exception {
        // 线程1
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                connectedLock.lock();
                System.out.println("-----1");
                Thread.sleep(5000);
                System.out.println("-----2");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("-----3");
            }
        }).start();
        // 线程2
        new Thread(() -> {
            try {
                Thread.sleep(1500);
                connectedLock.lock();
                System.out.println("=====1");
                connectedCondition.signalAll();//不会阻塞
                System.out.println("=====2");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("=====3");
            }
        }).start();
    }
}

运行结果:
-----1
-----2
-----3
=====1
=====2
=====3

注意:当前线程处于等待时,其他线程的其中一个线程会抢到锁,抢到锁的那个线程lock()不再阻塞,会往下执行。 

public class Test3 {
    private static ReentrantLock connectedLock = new ReentrantLock();
    private static Condition connectedCondition = connectedLock.newCondition();

    public static void main(String[] args) throws Exception {
        // 线程1
        new Thread(() -> {
            try {
                Thread.sleep(1000);
                connectedLock.lock();
                System.out.println("-----1");
                Thread.sleep(5000);
                System.out.println("-----2");
                // await 使当前线程等待,直到发出信号或中断,或者经过指定的等待时间。
                // 注意:当前线程处于等待时,其他线程的其中一个线程会抢到锁,抢到锁的那个线程lock()不再阻塞,会往下执行。
                connectedCondition.await(20, TimeUnit.SECONDS);//阻塞指定时间,其他线程唤醒会提前结束
                System.out.println("-----3");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("-----4");
            }
        }).start();
        // 线程2
        new Thread(() -> {
            try {
                Thread.sleep(1500);
                connectedLock.lock();
                System.out.println("=====1");
                connectedCondition.signalAll();//不会阻塞
                System.out.println("=====2");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                connectedLock.unlock();
                System.out.println("=====3");
            }
        }).start();
    }
}

运行结果:
-----1
-----2
=====1
=====2
=====3
-----3
-----4

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值