❯
返回顶部
幸运之星正在降临...
点击领取今天的签到奖励!
恭喜!您今天获得了{{mission.data.mission.credit}}积分
我的优惠劵
-
¥优惠劵使用时效:无法使用使用时效:
之前
使用时效:永久有效优惠劵ID:×
没有优惠劵可用!
好的好的。
mike老师,什么时候能把这个笔记给公布出来,因为上班时间很忙,现在每天只能浏览一节课的内容。想拿到笔记针对重点进行强化记忆。
1.线程死锁是指两个或多个线程相互持有对方需要的锁,导致这些都获取不到需要的锁,从而引起线程的永久等待无法继续执行的现象。
2.避免死锁一方面可以将所有线程对锁的获取的时序保持一致,另一方面可以给线程获取锁的操作设置超时时间,如果到达时限还未获取到锁,则将当前拥有的锁释放,等待随机一段时间后重试。
1.CountDownLatch继承AQS,使用了AQS的共享锁模式。使用state作为计数器,CLH队列实现线程等待。在初始化CDL的时候会定义计数器的值,每次调用countDown()都会使state-1,当state==0的时候会唤醒所有的await()的线程。
2.CDL的核心方法有:
CDL(int count) 构造函数,在构造的时候设置state的初始值;
countDown() 使state - 1,调用releaseShared(1);
await() 获取锁,如果没有获取成功,则将当前线程包装成Node加入CLH队列尾部,然后进行自旋获取锁,直到成功,调用acquireSharedInterruptibly()。
3.使用场景:
1⃣️在一个方法里需要组装各个接口返回的数据,可以在每个线程里各自获取各自接口的数据,主线程await(),等主线程获取到锁以后,再进行数据的组装;
2⃣️在测试时模拟并发请求,设置CDL(1),所有子线程全部await(),等所有子线程初始化完毕以后,主线程countDown()。
synchronized锁升级流程图
读锁获取锁流程图
写锁获取锁流程图
可重入读写锁在可重入锁的基础上扩展了读写分离的功能。在读写锁中,可以根据读和写来选择性的使用锁,读锁是共享锁,支持多个线程同时访问,所以效率比可重入锁更高;写锁和可重入锁一样是独占锁支持可重入。
另外,写锁可降级为读锁,保证了线程安全的基础上也提高了效率。
ReentrantLock是jdk提供的可重入锁,跟synchronized一样,也是为了保证在同一时刻只有一个线程能进入被锁的代码块,从而保证原子性。
ReentrantLock是基于AQS实现的锁,通过state来标记锁的状态,使用CLH队列来实现线程等待。当线程获取锁的时候,获取成功则执行代码,如果获取锁失败则会将当前线程组装到一个Node节点中,然后添加到CLH队尾。
ReentrantLock的公平锁和非公平锁的区别就是在获取锁的时候,公平锁会判定节点的前面是否还有在等待的线程节点,如果没有再进行CAS操作获取锁;而非公平锁则不会判断前面是否有等待节点直接进行CAS操作。
ReentrantLock的可重入实现是在获取锁的时候,如果发现锁的状态是有锁,则判断当前锁的线程是否和当前线程是同一线程,如果是,则将state+1,当前线程获得锁成功。同理,在解锁时,必须要state=0才解锁成功。
额,写错了,第一点是ReentrantLock只能用于代码块的使用,sync可以在普通方法、静态方法、代码块上使用。