JUC-公平锁&可重入锁&自旋锁&死锁

公平锁

先来先服务,不允许插队

 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
复制代码

非公平锁

允许插队,一般默认非公平锁,效率更高

public ReentrantLock() {
        sync = new NonfairSync();
    }
复制代码

可重入锁

即允许同一个线程多次获取同一把锁

实现:synchronized,ReentrantLock

  1. 对象A有两个同步方法a,b。
  2. 当我们进入同步方法a时我们获取了对象A的锁
  3. 在a中我们调用b则需要再次获得对象A的锁。这是被允许的
public class LockTest {
    public static void main(String[] args) {
        new Thread(()->{
            a();
        }).start();
    }
    public static synchronized void a(){
        System.out.println("a");
        b();
    }
    public static synchronized void b(){
        System.out.println("b");
    }
}
复制代码

自旋锁

  1. 一个线程A等待对象A的锁时
  2. 对象A的锁已经被线程B获取了。
  3. 线程A进入while循环等待而不是sleep
public static void main(String[] args) throws InterruptedException {
        myLock myLock=new myLock();
        // 线程0 获取锁后休息2秒
        new Thread(()->{
            myLock.mylock();
            try{
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                myLock.myunlock();
            }

        }).start();
        TimeUnit.SECONDS.sleep(1);
        //在线程0获取锁休息的时候,线程1不断的自旋等待锁的释放
        new Thread(()->{
            try{
                myLock.mylock();
            }finally {
                myLock.myunlock();
            }

        }).start();
    }
}
复制代码
class myLock{
    private AtomicReference<Thread> atomicReference=new AtomicReference<>();
    public void mylock(){
        Thread thread=Thread.currentThread();
        System.out.println(thread.getName()+"->>mylock");
        // 不断循环等待
        while(!atomicReference.compareAndSet(null,thread)){};
    }
    public void myunlock(){
        Thread thread=Thread.currentThread();
        System.out.println(thread.getName()+"->>myunlock");
        // 释放
        atomicReference.compareAndSet(thread,null) ;}
}

复制代码

死锁

  1. 线程A等待锁a,但锁a已经被线程B获取,陷入等待
  2. 线程B等待锁b,但锁b已经被线程A获取,陷入等待
  3. 相互等待永无止境

产生死锁的必要条件:

  • 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用。
  • 请求和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不可抢占:资源不能被抢占,即资源只能被进程在完成任务后自愿释放
  • 循环等待:在发生死锁时,必然存在一个进程–资源的环形链。

死锁排查

jps -l 查看进程
jstack 查找死锁

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享