Java可重入锁的实现原理与应用场景
可重入锁,从字面来理解,就是可以重复进入的锁。
可重入锁,也叫做递归锁,指的是同一线程外层函数获得锁之后,内层递归函数仍然有获取该锁的代码,但不受影响。
在JAVA环境下ReentrantLock和synchronized都是可重入锁。
synchronized是一个可重入锁。在一个类中,如果synchronized方法1调用了synchronized方法2,方法2是可以正常执行的,这说明synchronized是可重入锁。否则,在执行方法2想获取锁的时候,该锁已经在执行方法1时获取了,那么方法2将永远得不到执行。
可重入锁在什么场景使用呢?
可重入锁主要用在线程需要多次进入临界区代码时,需要使用可重入锁。具体的例子,比如上文中提到的一个synchronized方法需要调用另一个synchronized方法时。
可重入锁的实现原理是怎么样的?
加锁时,需要判断锁是否已经被获取。如果已经被获取,则判断获取锁的线程是否是当前线程。如果是当前线程,则给获取次数加1。如果不是当前线程,则需要等待。
释放锁时,需要给锁的获取次数减1,然后判断,次数是否为0了。如果次数为0了,则需要调用锁的唤醒方法,让锁上阻塞的其他线程得到执行的机会。
下面是一个用synchronized实现的例子:
public class ReentrantTest implements Runnable {
public synchronized void get() {
System.out.println(Thread.currentThread().getName());
set();
}
public synchronized void set() {
System.out.println(Thread.currentThread().getName());
}
public void run() {
get();
}
public static void main(String[] args) {
ReentrantTest rt = new ReentrantTest();
for(;;){
new Thread(rt).start();
}
}
}
整个过程没有发生死锁的情况,截取一部分输出结果如下:
Thread-8492
Thread-8492
Thread-8494
Thread-8494
Thread-8495
Thread-8495
Thread-8493
Thread-8493
set()和get()同时输出了线程名称,表明即使递归使用synchronized也没有发生死锁,证明其是可重入的。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接
相关文章
SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤
我们开发 SpringBoot 项目有时我们会需要打包成 war 包,放入外置的 Tomcat 中进行运行,或者使用工具idea直接启动,便于开发调试,本文给大家分享SpringBoot项目打包成war包并部署在tomcat上运行的操作步骤,感兴趣的朋友一起看看吧2024-03-03
Springboot使用Rabbitmq的延时队列+死信队列实现消息延期消费
本文介绍了RabbitMQ的延时队列和死信队列,解释了它们的工作原理及其应用场景,延时队列允许消息在设定的时间后被消费,结合实际案例,展示了如何实现和使用延时队列和死信队列,感兴趣的朋友一起看看吧2025-01-01
使用jquery 的ajax 与 Java servlet的交互代码实例
这篇文章主要介绍了使用jquery 的ajax 与 Java servlet的交互代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2019-09-09
Java源码解析HashMap的tableSizeFor函数
今天小编就为大家分享一篇关于Java源码解析HashMap的tableSizeFor函数,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧2019-01-01


最新评论