可重入锁和不可重入锁的区别

一、可重入锁与不可重入锁的区别

可重入锁和不可重入锁的最大区别在于,可重入锁允许同一个线程在获得锁之后再次获得该锁,而不可重入锁不允许。

在使用不可重入锁时,如果一个线程已经获得该锁,那么在该线程释放该锁之前,其他所有线程都无法获得这个锁。而在使用可重入锁时,如果一个线程已经获得锁,那么在该线程释放该锁之前,它可以再次获得该锁而不会被阻塞。

二、可重入锁的使用场景

可重入锁通常应用于递归或者嵌套的代码中。在代码嵌套调用的过程中,如果使用不可重入锁,那么程序将会阻塞,可能会导致死锁现象的发生。

举例来说,在使用不可重入锁时,如果在一个线程已经获得锁的情况下,又尝试获得该锁,那么这个线程将会被一直阻塞,直到另外一个线程释放该锁。而在使用可重入锁时,同一个线程可以多次获得锁,因此不会导致死锁现象的发生。

三、可重入锁的实现原理

可重入锁最常用的实现方式是通过计数器来实现的,每次获得锁时,计数器加1,每次释放锁时,计数器减1。只有当计数器为0时,其他线程才有机会获得该锁。这样就能够保证同一个线程可以多次获得该锁,而其他线程只有在该锁被彻底释放时才能获得该锁。

四、synchronized可重入锁

在Java语言中,synchronized关键字是一种可重入锁。这意味着如果一个线程已经获得了某个对象上的synchronized锁,那么它可以再次获得该对象锁而不会被阻塞。

synchronized锁的实现方式并不是通过计数器来实现的。它是通过线程持有的对象监视器(也可以称为锁对象)来实现的。当线程请求进入一段同步代码时,如果该锁没有被其他线程占用,那么该线程会获得该锁,同时锁对象的计数器会+1。如果同一线程再次请求该锁,那么线程可以再次获得该锁,同时计数器也会再次+1。当线程执行完同步代码块并释放锁时,该线程持有的锁对象的计数器会-1。只有当该计数器的值为0时,锁对象才会被解锁,这样其他线程才有机会获得该锁。

五、可重入锁和不可重入锁的区别

1、可重入锁允许同一个线程在获得锁之后再次获得该锁,而不可重入锁不允许。

2、在使用不可重入锁时,如果一个线程已经获得该锁,那么在该线程释放该锁之前,其他所有线程都无法获得这个锁。而在使用可重入锁时,如果一个线程已经获得锁,那么在该线程释放该锁之前,它可以再次获得该锁而不会被阻塞。

3、可重入锁通常用于递归嵌套的代码中,而不可重入锁一般只用于独占式地获得资源。

示例代码

// 可重入锁的示例
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {
    private static final ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    work();
                }
            }).start();
        }
    }

    private static void work() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "获得了锁");
            nestedWork();
        } finally {
            lock.unlock();
        }
    }

    private static void nestedWork() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "再次获得了锁");
        } finally {
            lock.unlock();
        }
    }
}

// 不可重入锁的示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class NonReentrantLockDemo {
    private static final Lock lock = new ReentrantLock();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                work();
            }
        }, "Thread-A").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                work();
            }
        }, "Thread-B").start();
    }

    private static void work() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "获得了锁");
            nestedWork();
        } finally {
            lock.unlock();
        }
    }

    private static void nestedWork() {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + "尝试获得锁但被阻塞了");
        } finally {
            lock.unlock();
        }
    }
}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/199136.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-04 19:14
下一篇 2024-12-04 19:14

相关推荐

  • Python中new和init的区别

    new和init都是Python中常用的魔法方法,它们分别负责对象的创建和初始化,本文将从多个角度详细阐述它们的区别。 一、创建对象 new方法是用来创建一个对象的,它是一个类级别…

    编程 2025-04-29
  • Sublime Test与Python的区别

    Sublime Text是一款流行的文本编辑器,而Python是一种广泛使用的编程语言。虽然Sublime Text可以用于编写Python代码,但它们之间有很多不同之处。接下来从…

    编程 2025-04-29
  • Shell脚本与Python脚本的区别

    本文将从多个方面对Shell脚本与Python脚本的区别做详细的阐述。 一、语法差异 Shell脚本和Python脚本的语法存在明显差异。 Shell脚本是一种基于字符命令行的语言…

    编程 2025-04-29
  • Python中while语句和for语句的区别

    while语句和for语句是Python中两种常见的循环语句,它们都可以用于重复执行一段代码。然而,它们的语法和适用场景有所不同。本文将从多个方面详细阐述Python中while语…

    编程 2025-04-29
  • Web程序和桌面程序的区别

    Web程序和桌面程序都是进行软件开发的方式,但是它们之间存在很大的区别。本文将从多角度进行阐述。 一、运行方式 Web程序运行于互联网上,用户可以通过使用浏览器来访问它。而桌面程序…

    编程 2025-04-29
  • TensorFlow和Python的区别

    TensorFlow和Python是现如今最受欢迎的机器学习平台和编程语言。虽然两者都处于机器学习领域的主流阵营,但它们有很多区别。本文将从多个方面对TensorFlow和Pyth…

    编程 2025-04-28
  • MySQL bigint与long的区别

    本文将从数据类型定义、存储空间、数据范围、计算效率、应用场景五个方面详细阐述MySQL bigint与long的区别。 一、数据类型定义 bigint在MySQL中是一种有符号的整…

    编程 2025-04-28
  • 麦语言与Python的区别

    麦语言和Python都是非常受欢迎的编程语言。它们各自有自己的优缺点和适合的应用场景。本文将从语言特性、语法、生态系统等多个方面,对麦语言和Python进行详细比较和阐述。 一、语…

    编程 2025-04-28
  • Python与C语言的区别和联系

    Python与C语言是两种常用的编程语言,虽然两者都可以用于编写软件程序,但是它们之间有很多不同之处。本文将从多个方面对Python与C语言的区别和联系进行详细的阐述。 一、语法特…

    编程 2025-04-28
  • Python中深拷贝和浅拷贝的区别

    本文将从以下几个方面对Python中深拷贝和浅拷贝的区别做详细的阐述,包括:拷贝的含义、变量和对象的区别、浅拷贝的示例、深拷贝的示例、可变对象和不可变对象的区别、嵌套的数据结构以及…

    编程 2025-04-28

发表回复

登录后才能评论