java之可重入锁和递归锁理论知识

    xiaoxiao2025-07-22  6

    大厂面试题:公平锁/非公平锁/重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁。大厂面试题:公平锁/非公平锁/重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁。

    1、什么是可重入锁(递归锁) 

           可重入锁(也叫递归锁):指的是同一线程外层函数获得锁之后,内层递归函数仍然可以获取该锁的代码,在同一线程在外层方法获取锁的时候+,在进入内层方法会自动获取锁。

    也就是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块

    2、可重入锁(递归锁)举例

    进入method1方法跟进入method2方法获取的是同一把锁

        public synchronized void method1(){

            System.out.println("sysn method1");

            method2();

        }

     

        private synchronized void method2() {

            System.out.println("syn method2");

        }

    3、可重入锁(递归锁)作用

           最大的作用:避免死锁。

    4、可重入锁代码验证

    Demo one:

    /**

     * 可重入锁(递归锁)

     *

     * 指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,

     * 在同一个线程外层方法获取锁的时候,在进入内层方法就会自动获取锁

     *

     * 也就是说,线程可以进入任何一个它已经拥有锁的代码块。

     *

     * sychronized是一个典型的可重入锁

     */

    public class ReentrantLockDemoOne {

        public synchronized void sendSMS(){

            System.out.println(Thread.currentThread().getName()+" invoke sendSMS");

            sendEmail();

        }

     

        private synchronized void sendEmail() {

            System.out.println(Thread.currentThread().getName()+" invoke sendEmail");

        }

     

        public static void main(String[] args) {

            ReentrantLockDemoOne reentrantLockDemoOne = new ReentrantLockDemoOne();

            new Thread(()->{

                reentrantLockDemoOne.sendSMS();

            },"t1").start();

     

            new Thread(()->{

                reentrantLockDemoOne.sendSMS();

            },"t2").start();

        }

    }

    程序执行结果如下:

    Demo two:

    import java.util.concurrent.locks.Lock;

    import java.util.concurrent.locks.ReentrantLock;

     

    /**

     * 可重入锁(递归锁)

     *

     * 指的是同一线程外层函数获得锁之后,内层递归函数仍然能获取该锁的代码,

     * 在同一个线程外层方法获取锁的时候,在进入内层方法就会自动获取锁

     *

     * 也就是说,线程可以进入任何一个它已经拥有锁的代码块。

     *

     * ReentrantLock是一个典型的可重入锁

     */

    public class ReentrantLockDemoTwo {

     

     

    public static void main(String[] args) {

    Phone phone = new Phone();

            Thread t1 = new Thread(phone,"t1");

            Thread t2 = new Thread(phone,"t2");

            t1.start();

            t2.start();

        }

    }

     

    class Phone implements Runnable{

        private Lock lock = new ReentrantLock();

     

        @Override

        public void run() {

            sendSMS();

        }

     

        private void sendSMS() {

            lock.lock();

            try {

                // 线程可以进入任何一个它已经拥有锁的代码块

                System.out.println(Thread.currentThread().getName()+" invoke sendSMS");

            } finally {

                lock.unlock();

            }

            sendEmail();

        }

     

        private void sendEmail() {

            lock.lock();

            try {

                // 线程可以进入任何一个它已经拥有锁的代码块

                System.out.println(Thread.currentThread().getName()+" invoke sendEmail");

            } finally {

                lock.unlock();

            }

        }

    }

    程序执行结果如下:

    Demo Three:

    private void sendSMS() {

            lock.lock();

            lock.lock();

            try {

                // 线程可以进入任何一个它已经拥有锁的代码块

                System.out.println(Thread.currentThread().getName()+" invoke sendSMS");

            } finally {

                lock.unlock();

                lock.unlock();

            }

            sendEmail();

    }

    程序执行结果如下:

    Demo four:

        private void sendSMS() {

            lock.lock();

            lock.lock();

            try {

                // 线程可以进入任何一个它已经拥有锁的代码块

                System.out.println(Thread.currentThread().getName()+" invoke sendSMS");

                sendEmail();

            } finally {

                lock.unlock();

            }

    }

    程序执行结果如下:程序一直阻塞,因为锁资源一直未释放

    最新回复(0)