阿里P5-锁相关
1.产生死锁的必要条件
死锁概念及产生原理
概念: 多个并发进程因争夺系统资源而产生相互等待的现象。
原理: 当一组进程中的每个进程都在等待某个事件发生,而只有这组进程中的其他进程才能触发该事件,这就称这组进程发生了死锁。
本质原因:
1)系统资源有限。
2)进程推进顺序不合理。
死锁产生的4个必要条件
1、互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、部分分配: 一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
这里对死锁的必要条件的解读,网上很多技术博客的文章都有分歧,我在这儿也只是说一下自己的理解。首先我觉得这里的必要条件按照数学上的理解是没问题的,就是一旦发生了死锁那么必然会满足以上的四个条件,如果有一条情况不满足,那么肯定不会产生死锁。所以我们预防死锁的方法就是通过解除这4个必要条件来实现。但是满足以上的四个条件是否会造成死锁呢?不一定,因为可能Cpu的调度方式恰好避开了死锁的进程执行顺序。
2.按锁的分类,可以分为哪几类锁,他们之间的特性是什么?
这里推荐一篇写的详细的博文:
https://blog.youkuaiyun.com/nalanmingdian/article/details/77800355
3.synchronized和ReentrantLock的区别
a.Synchronized,它就是一个:非公平,悲观,独享,互斥,可重入的重量级锁
b.ReentrantLock,它是一个:默认非公平但可实现公平的,悲观,独享,互斥,可重入,重量级锁。
ReentrantLock的高级操作
中断等待
ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候。
线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定。
如果使用 synchronized ,如果A不释放,B将一直等下去,不能被中断 如果 使用ReentrantLock,如果A不释放,可以使B在等待了足够长的时间以后,中断等待,而干别的事情
ReentrantLock获取锁定有三种方式:
lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false
tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到获取锁定,或者当前线程被别的线程中断
可实现公平锁
对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。
锁绑定多个条件
锁绑定多个条件是指一个ReentrantLock对象可以同时绑定多个Condition对象,而在synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件,如果要和多于一个的条件关联的时候,就不得不额外地添加一个锁,而ReentrantLock则无须这样做,只需要多次调用newCondition()方法即可。
synchronized的优势
synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
应用场景
在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;