13 各种锁的理解

各种锁

1、公平锁、非公平锁

公平锁:非常公平,不能插队,必须先来后到

非公平锁:非常不公平,可以插队,(默认都是非公平的)

    public ReentrantLock() {
        sync = new NonfairSync();
    }

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

	Lock lock = new ReentrantLock(true);

2、可重入锁

可重入锁(递归锁)

拿到了外面的锁,就可以拿到里面的锁(自动获得)

synchronized版

public class Demo01 {
    public static void main(String[] args) {
        Phone phone = new Phone();

        new Thread(()->{
            phone.send();
        },"A").start();



        new Thread(()->{
            phone.send();
        },"B").start();
    }

}

class Phone{

     public synchronized void send(){
            System.out.println(Thread.currentThread().getName()+"send");
            call();
        }

    public synchronized void call() {
        System.out.println(Thread.currentThread().getName() + "call");

    }
}

lock版

public class Demo02 {
    public static void main(String[] args) {
        Phone2 phone = new Phone2();

        new Thread(()->{
            phone.send();
        },"A").start();



        new Thread(()->{
            phone.send();
        },"B").start();
    }

}

class Phone2{

    Lock lock = new ReentrantLock();

    public  void send(){
        lock.lock();//锁必须配对 否则就会死在里面
        try {
            System.out.println(Thread.currentThread().getName()+"send");
            call();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public  void call() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "call");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

3、自旋锁

spinlock

public class SpinLock {

    //Thread  null
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    //加锁
    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"==> myLock");

        while (!atomicReference.compareAndSet(null,thread));
    }

    //解锁
    public void myUnLock() {
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"==> myLock");

        atomicReference.compareAndSet(thread,null);

    }
}

4、死锁

public class DeadLock {
    public static void main(String[] args) {

        String lockA = "A";
        String lockB = "B";

        new Thread(new MyThread(lockA,lockB),"t1").start();
        new Thread(new MyThread(lockB,lockA),"t2").start();
    }
}

class MyThread implements Runnable{

    private String lockA;
    private String lockB;

    public MyThread(String lockA,String lockB){
        this.lockA = lockA;
        this.lockA = lockB;
    }


    @Override
    public void run() {
        synchronized (lockA){
            System.out.println(Thread.currentThread().getName()+"lock"+lockA+"=>"+lockB);

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            synchronized (lockB){
                System.out.println(Thread.currentThread().getName()+"lock"+lockB+"=>"+lockA);
            }
        }
    }
}

怎么排除死锁

  1. 使用jsp-l 定位进程号 到idea terminal 输入
  2. 使用jstack 进程号

面试,工作中!排查问题:

  1. 日志
  2. 堆栈
posted @   flypiggg  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示