JUC入门(二)
Lock8锁问题,之前有一个Lock8锁的笔记 https://www.cnblogs.com/pangbi/p/14972548.html
公平锁和非公平锁
ReentrantLock()在没有传入参数的情况下,就是默认为非公平锁
非公平锁:可能会有线程饿死的情况,但执行效率高
公平锁:有一种排队依次执行的感觉,效率相对低
可重入锁
synchronized(隐式的)和Lock(显示)都是可重入锁
例子如下:
public class KeChongRuLock { public static void main(String[] args){ Object o = new Object(); new Thread(()->{ synchronized (o){ System.out.println("外层"); synchronized (o){ System.out.println("中层"); synchronized (o){ System.out.println("内层"); } } } },"A").start(); } }
ReentrantLock lock = new ReentrantLock(); new Thread(()->{ try{ lock.lock(); System.out.println(Thread.currentThread().getName()+"外层"); try{ lock.lock(); System.out.println(Thread.currentThread().getName()+"内层"); }finally { lock.unlock(); } }finally { lock.unlock(); } },"BB").start();
死锁
两个或两个以上进程在执行过程中,因为争夺资源而造成一种互相等待的现象,如果没有外力干涉,他们无法再执行下去
产生死锁的原因
1)系统资源不足
2)进程运行推进顺序不合适
3)资源分配不当
死锁的例子如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class DeadLock { public static void main(String[] args){ Object a = new Object(); Object b = new Object(); new Thread(()->{ synchronized (a){ System.out.println("获得了a锁,试图获取B锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b){ System.out.println("成功获取到了B锁"); } } },"a").start(); new Thread(()->{ synchronized (b){ System.out.println("获得了b锁,试图获取a锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (a){ System.out.println("成功获取到了a锁"); } } },"a").start(); } }
验证是否是死锁
步骤一:jsp -l (但是要先配置jdk jps的环境变量才可以这样搞)
步骤二:根据查出来的内容,找到对应的编号,然后通过 (jstack 6252)查询情况,可以看到 下图中两个线程死锁了