zoukankan      html  css  js  c++  java
  • 各种锁的理解

    各种锁的理解

    1、公平锁、非公平锁

    公平锁: 非常公平, 不能够插队,必须先来后到!
    非公平锁:非常不公平,可以插队 (默认都是非公平)

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

    2、可重入锁

    可重入锁(递归锁)

    image-20200805122020949

    Synchronized

    // Synchronized
    public class Demo01 {
        public static void main(String[] args) {
            Phone phone = new Phone();
    
            new Thread(()->{
                phone.sms();
            },"A").start();
    
    
            new Thread(()->{
                phone.sms();
            },"B").start();
        }
    }
    
    class Phone{
    
        public synchronized void sms(){
            System.out.println(Thread.currentThread().getName() + "sms");
            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.sms();
            },"A").start();
    
    
            new Thread(()->{
                phone.sms();
            },"B").start();
        }
    }
    
    class Phone2{
        Lock lock = new ReentrantLock();
    
        public void sms(){
            lock.lock(); // 细节问题:lock.lock(); lock.unlock(); // lock 锁必须配对,否则就会死在里面
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "sms");
                call(); // 这里也有锁
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                lock.unlock();
            }
    
        }
    
        public void call(){
    java
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "call");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    

    3、自旋锁

    spinlock

    image-20200805165613951

    /**
     * 自旋锁
     */
    public class SpinlockDemo {
    
        // int   0
        // 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() + "==> myUnlock");
            atomicReference.compareAndSet(thread,null);
        }
    
    
    
    }
    

    测试

    public class TestSpinLock {
        public static void main(String[] args) throws InterruptedException {
    //        ReentrantLock reentrantLock = new ReentrantLock();
    //        reentrantLock.lock();
    //        reentrantLock.unlock();
    
            // 底层使用的自旋锁CAS
            SpinlockDemo lock = new SpinlockDemo();
    
    
            new Thread(()-> {
                lock.myLock();
    
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.myUnLock();
                }
    
            },"T1").start();
    
            TimeUnit.SECONDS.sleep(1);
    
            new Thread(()-> {
                lock.myLock();
    
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.myUnLock();
                }
    
            },"T2").start();
    
        }
    }
    

    image-20200805165802649

    4、死锁

    image-20200805165833642

    死锁测试-怎么排除死锁

    public class DeadLockDemo {
        public static void main(String[] args) {
    
            String lockA = "lockA";
            String lockB = "lockB";
    
            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.lockB = lockB;
        }
    
        @Override
        public void run() {
            synchronized (lockA){
                System.out.println(Thread.currentThread().getName() + "lock:"+lockA+"=>get"+lockB);
    
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                synchronized (lockB){
                    System.out.println(Thread.currentThread().getName() + "lock:"+lockB+"=>get"+lockA);
                }
    
            }
        }
    }
    

    解决方案

    1、使用 jps -l 定位进程号

    2、使用 jstack 进程号 找到死锁问题

    面试,工作中! 排查问题:
    1、日志
    2、堆栈信息

    视频参考https://www.bilibili.com/video/BV1B7411L7tE
    上一篇:原子引用

  • 相关阅读:
    [LeetCode]Contains Duplicate
    C++基础之泛型算法
    KMP算法
    [LeetCode]Shortest Palindrome
    [LeetCode]House Robber
    Palindrome Linked List leetcode
    Rotate Array leetcode
    Rotate Image LeetCode
    Rotate List leetcode
    Reorder List leetcode
  • 原文地址:https://www.cnblogs.com/junlinsky/p/13443394.html
Copyright © 2011-2022 走看看