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)资源分配不当

死锁的例子如下:

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();
    }
}
View Code

 

验证是否是死锁

  步骤一:jsp -l      (但是要先配置jdk jps的环境变量才可以这样搞)

 

  步骤二:根据查出来的内容,找到对应的编号,然后通过 (jstack 6252)查询情况,可以看到 下图中两个线程死锁了

 

posted @ 2021-09-10 23:39  古比  阅读(29)  评论(0编辑  收藏  举报