Java--JUC--公平锁,非公平锁,可重入锁,自旋锁,死锁

  1. 公平锁
  2. 非公平锁
  3. 可重入锁(递归锁)
    1.  
    2.  

      package com.model.lock;
      
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;
      
      /**
       * @Description:测试类
       * @Author: 张紫韩
       * @Crete 2021/6/10 16:14
       */
      public class LockDemo {
          /**
           * 1.公平锁,非公平锁
           *  公平锁:不允许插队
           *  公平锁:允许插队
           * public ReentrantLock(boolean fair) {
           *         sync = fair ? new FairSync() : new NonfairSync();
           *     }
           * 2.可重入锁(递归锁)
           *   拿到外面的锁,就会自动获得里面的锁(大门得锁,和卧室得锁)
           *   外面的锁,包含里面的锁,只有当里面得锁释放之后,外面得锁锁才能释放
           *   是一种包含关系,先拿到后释放,后拿到先释放
           *
           * 3.自旋锁
           * 4.死锁
           * */
      
          public static void main(String[] args) {
      /*
              Lock lock=new ReentrantLock(true); //公平锁
              Lock lock1=new ReentrantLock();//非公平锁,默认
              */
              Phone phone=new Phone();
              new Thread(() ->{
                  phone.msg();
              },"A").start();
              new Thread(() ->{
                  phone.msg();
              },"B").start();
      
          }
      }
      
      class Phone{
          //lock锁必须进行配对操作,上锁和解锁的相对应
          Lock lock=new ReentrantLock();
          public void msg(){
              lock.lock();
              try {
                  System.out.println(Thread.currentThread().getName()+"执行了msg");
                  TimeUnit.SECONDS.sleep(2);
                  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();
              }
          }
      
      }

       

        

       
  4. 自旋锁
    1.  

       

       

    2. package com.model.lock;
      
      import java.util.ArrayList;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.atomic.AtomicReference;
      
      /**
       * @Description:测试类
       * @Author: 张紫韩
       * @Crete 2021/6/10 17:08
       */
      public class SpinLockDemo {
      
          //在类里面创建接口,类不能使用new 类名(),在使用快捷键形成变量的方式
           AtomicReference<Thread> atomicReference=new AtomicReference<>();
          public void myLock(){
              Thread thread = Thread.currentThread();
      //        System.out.println(Thread.currentThread().getName()+"开始获取锁操作");
              //加锁, 如果一直获取不到锁,就会一直在这里转,自旋,知道拿到锁
              while (!atomicReference.compareAndSet(null, thread)){};
              System.out.println(Thread.currentThread().getName()+"获得了锁");
      
          }
          public void myUnLock(){
              Thread thread=Thread.currentThread();
              if (atomicReference.compareAndSet(thread, null)){
                  System.out.println(Thread.currentThread().getName()+"释放锁成功");
              }
          }
      }
      
      class TestSpinLock{
          public static void main(String[] args) {
              SpinLockDemo spinLockDemo=new SpinLockDemo();
      
              new Thread(() ->{
                  spinLockDemo.myLock();
                  try {
                      TimeUnit.SECONDS.sleep(3);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  spinLockDemo.myUnLock();
              },"A").start();
      
              new Thread(() ->{
                  try {
                      TimeUnit.SECONDS.sleep(1);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  spinLockDemo.myLock();
                  try {
                      TimeUnit.SECONDS.sleep(3);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  spinLockDemo.myUnLock();
              },"B").start();
      
      
          }
      }

       

       

       

       
  5. 死锁
    1.  
      package com.model.lock;
      
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.atomic.AtomicReference;
      import java.util.concurrent.locks.Lock;
      import java.util.concurrent.locks.ReentrantLock;
      
      /**
       * @Description:测试类
       * @Author: 张紫韩
       * @Crete 2021/6/10 16:14
       */
      public class LockDemo {
          /**
           * 1.公平锁,非公平锁
           *  公平锁:不允许插队
           *  公平锁:允许插队
           * public ReentrantLock(boolean fair) {
           *         sync = fair ? new FairSync() : new NonfairSync();
           *     }
           * 2.可重入锁(递归锁)
           *   拿到外面的锁,就会自动获得里面的锁(大门得锁,和卧室得锁)
           *   外面的锁,包含里面的锁,只有当里面得锁释放之后,外面得锁锁才能释放
           *   是一种包含关系,先拿到后释放,后拿到先释放
           *
           * 3.自旋锁
           * 4.死锁
           * */
      
          public static void main(String[] args) {
      /*
              Lock lock=new ReentrantLock(true); //公平锁
              Lock lock1=new ReentrantLock();//非公平锁,默认
              */
              Phone phone=new Phone();
              new Thread(() ->{
                  phone.msg();
              },"A").start();
              new Thread(() ->{
                  phone.msg();
              },"B").start();
      
       
      
      
          }
      }
      
      class Phone{
          //lock锁必须进行配对操作,上锁和解锁的相对应
          Lock lock=new ReentrantLock();
          public void msg(){
              lock.lock();
              try {
                  System.out.println(Thread.currentThread().getName()+"执行了msg");
                  TimeUnit.SECONDS.sleep(2);
                  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();
              }
          }
      
      }

       

    2. 解决方式,配查问题: 
      1. 查看日志
      2. 查看堆栈信息  
      3. 使用  :jps -l   ,查看当前运行的进程号
      4. 使用 jstack 死锁进程号,查看堆栈信息
posted @ 2021-06-10 19:50  张紫韩  阅读(48)  评论(0编辑  收藏  举报