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

Posted 张紫韩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 死锁进程号,查看堆栈信息

以上是关于java--JUC--公平锁,非公平锁,可重入锁,自旋锁,死锁的主要内容,如果未能解决你的问题,请参考以下文章

Java 独占锁与共享锁公平锁与非公平锁可重入锁

图解 --乐观锁 悲观锁 可重入锁 独占锁 共享锁 公平锁 非公平锁

Java中锁分类

Java的锁:公平锁,非公平锁,可重入锁,自旋锁,独占锁(写锁) / 共享锁(读锁) / 互斥锁...

Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

ReentrantLock(重入锁)简单源码分析