JUC(16)锁

  • Post author:
  • Post category:其他




公平锁 ,非公平锁

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

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

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



可重入锁(递归锁)

拿到外面的锁 就能自动获取里面的锁

public class CASDmeo {
 
        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");
        }
    }



自旋锁

自定义自旋锁

public class SpinlockDemo {
   
    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);
    }
}



死锁

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。 因此我们举个例子来描述,如果此时有一个线程T1,按照先锁a再获得锁b的的顺序获得锁,而在此同时又有另外一个线程T2,按照先锁b再锁a的顺序获得锁

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 进程号 找到死锁问题



版权声明:本文为OVO_LQ_Start原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。