Java并发编程(1):可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁。线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。
当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。然而,由于内置锁是可重入的,因此如果摸个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。“重入”意味着获取锁的操作的粒度是“线程”,而不是调用。重入的一种实现方法是,为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程所持有,当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1,如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会相应地递减。当计数值为0时,这个锁将被释放。
重入进一步提升了加锁行为的封装性,因此简化了面向对象并发代码的开发。分析如下程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Father
{
public synchronized void doSomething(){
......
}
}
public class Child extends Father
{
public synchronized void doSomething(){
......
super .doSomething();
}
}
|
子类覆写了父类的同步方法,然后调用父类中的方法,此时如果没有可重入的锁,那么这段代码件产生死锁。
由于Fither和Child中的doSomething方法都是synchronized方法,因此每个doSomething方法在执行前都会获取Child对象实例上的锁。如果内置锁不是可重入的,那么在调用super.doSomething时将无法获得该Child对象上的互斥锁,因为这个锁已经被持有,从而线程会永远阻塞下去,一直在等待一个永远也无法获取的锁。重入则避免了这种死锁情况的发生。
同一个线程在调用本类中其他synchronized方法/块或父类中的synchronized方法/块时,都不会阻碍该线程地执行,因为互斥锁时可重入的。
from: http://www.importnew.com/20487.html
原文出处: 兰亭风雨
Java并发编程(1):可重入内置锁相关推荐
- Java并发编程实战————可重入内置锁
引言 在<Java Concurrency in Practice>的加锁机制一节中作者提到: Java提供一种内置的锁机制来支持原子性:同步代码块."重入"意味着获取 ...
- Java 并发编程之可重入锁 ReentrantLock
Java 提供了另外一个可重入锁,ReentrantLock,位于 java.util.concurrent.locks 包下,可以替代 synchronized,并且提供了比 synchronize ...
- Java并发编程-ReentrantLock可重入锁
目录 1.ReentrantLock可重入锁概述 2.可重入 3.可打断 4.锁超时 5.公平锁 6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchron ...
- Java并发编程实战 第13章 显式锁
接口Lock的实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock Reentra ...
- java重入锁_java并发编程:可重入锁是什么?
释义 广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁.ReentrantLock和sync ...
- 【Java 并发编程】指令重排序规范 ( happens-before 先行发生原则 )
文章目录 一.指令重排序规范 二.happens-before 先行发生原则 一.指令重排序规范 指令重排指的是 , 线程中如果两行代码 没有逻辑上的上下关系 , 可以对代码进行 重新排序 ; JVM ...
- Java并发编程之ReentrantLock重入锁
ReentrantLock: 源码层面分析: public class ReentrantLock implements Lock, java.io.Serializable {private sta ...
- 【Java并发编程】:使用synchronized获取互斥锁
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...
- Java并发编程之指令重排序
在我们面试过程中,通常避免不了会被问到什么是指令重排序?本文就这个问题进行探索. 重排序 前言 一.重排序种类 二.happens-before 三.重排序 1.数据依赖性 2. as-if-seri ...
最新文章
- 20155328 《信息安全系统设计基础》第六周 课堂提交补充
- 二十、“安化辞骚千万卒,康吾故土祭吾躯”(2021.6.14)
- ELK日志分析平台(elasticsearch)
- php 终止程序的方法——return、exit()、die()
- 方舟非主机服务器无限距离,方舟非专业服务器距离限制怎么解除 | 手游网游页游攻略大全...
- 涂国旗(洛谷P3392题题解,Java语言描述)
- PyTorch 1.0 中文文档:自动求导机制
- Java 用反射设置对象的属性值
- mysql拼装字段_Mysql 实现字段拼接的三个函数
- C#爬虫项目:SWorld阅读
- HS8145X6华为界面telnet23账号密码重置
- 怎么把多个音频合并成一个音频?
- JAVA 超详细 将文件夹目录打包为 ZIP 压缩包并下载
- 支付宝sdk集成,报系统繁忙 请稍后再试(ALI64)
- macOS SwiftUI 进度指示器组件规范之 01 进度指标是什么 Progress Indicators
- VR和AR只是入门,真正的元宇宙远不止于此
- 向量的加减(输出重载)
- Matlab 主曲率、平均曲率、高斯曲率
- opcache 缓存_缓存帽子戏法:Zend Opcache,Etags和查询缓存
- 自动化测试工作考核指标
热门文章
- 机器学习算法基础——数据特征预处理
- 你所知道及不知道的骗贷、中介、欺诈团伙是怎么样的
- 引擎讲解2--主要是MyISAM和InnoDB的区别
- 德勤:95%的受访公司将在2019年投资区块链
- Visual Studio 2013开发 mini-filter driver step by step (4) - 获取文件名
- Spring Boot - 自动配置实现原理
- IDEA-使用IDEA创建maven多模块父子工程
- Go语言线程与协程之间的关系之GMP模型
- arm-linux 交叉编译后程序,ARM交叉编译下,应用程序实践
- 为什么是get()和set()方法?