每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁。线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。

当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。然而,由于内置锁是可重入的,因此如果摸个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。“重入”意味着获取锁的操作的粒度是“线程”,而不是调用。重入的一种实现方法是,为每个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程所持有,当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1,如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会相应地递减。当计数值为0时,这个锁将被释放。

重入进一步提升了加锁行为的封装性,因此简化了面向对象并发代码的开发。分析如下程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
publicclass Father
{
    publicsynchronized void doSomething(){
        ......
    }
}
publicclass Child extendsFather
{
    publicsynchronized void doSomething(){
        ......
        super.doSomething();
    }
}

子类覆写了父类的同步方法,然后调用父类中的方法,此时如果没有可重入的锁,那么这段代码件产生死锁。

由于Fither和Child中的doSomething方法都是synchronized方法,因此每个doSomething方法在执行前都会获取Child对象实例上的锁。如果内置锁不是可重入的,那么在调用super.doSomething时将无法获得该Child对象上的互斥锁,因为这个锁已经被持有,从而线程会永远阻塞下去,一直在等待一个永远也无法获取的锁。重入则避免了这种死锁情况的发生。

同一个线程在调用本类中其他synchronized方法/块或父类中的synchronized方法/块时,都不会阻碍该线程地执行,因为互斥锁时可重入的。

from: http://www.importnew.com/20487.html

原文出处: 兰亭风雨

Java并发编程(1):可重入内置锁相关推荐

  1. Java并发编程实战————可重入内置锁

    引言 在<Java Concurrency in Practice>的加锁机制一节中作者提到: Java提供一种内置的锁机制来支持原子性:同步代码块."重入"意味着获取 ...

  2. Java 并发编程之可重入锁 ReentrantLock

    Java 提供了另外一个可重入锁,ReentrantLock,位于 java.util.concurrent.locks 包下,可以替代 synchronized,并且提供了比 synchronize ...

  3. Java并发编程-ReentrantLock可重入锁

    目录 1.ReentrantLock可重入锁概述 2.可重入 3.可打断 4.锁超时 5.公平锁 6.条件变量 Condition 1.ReentrantLock可重入锁概述 相对于 synchron ...

  4. Java并发编程实战 第13章 显式锁

    接口Lock的实现类: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock Reentra ...

  5. java重入锁_java并发编程:可重入锁是什么?

    释义 广义上的可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁.ReentrantLock和sync ...

  6. 【Java 并发编程】指令重排序规范 ( happens-before 先行发生原则 )

    文章目录 一.指令重排序规范 二.happens-before 先行发生原则 一.指令重排序规范 指令重排指的是 , 线程中如果两行代码 没有逻辑上的上下关系 , 可以对代码进行 重新排序 ; JVM ...

  7. Java并发编程之ReentrantLock重入锁

    ReentrantLock: 源码层面分析: public class ReentrantLock implements Lock, java.io.Serializable {private sta ...

  8. 【Java并发编程】:使用synchronized获取互斥锁

    在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...

  9. Java并发编程之指令重排序

    在我们面试过程中,通常避免不了会被问到什么是指令重排序?本文就这个问题进行探索. 重排序 前言 一.重排序种类 二.happens-before 三.重排序 1.数据依赖性 2. as-if-seri ...

最新文章

  1. 20155328 《信息安全系统设计基础》第六周 课堂提交补充
  2. 二十、“安化辞骚千万卒,康吾故土祭吾躯”(2021.6.14)
  3. ELK日志分析平台(elasticsearch)
  4. php 终止程序的方法——return、exit()、die()
  5. 方舟非主机服务器无限距离,方舟非专业服务器距离限制怎么解除 | 手游网游页游攻略大全...
  6. 涂国旗(洛谷P3392题题解,Java语言描述)
  7. PyTorch 1.0 中文文档:自动求导机制
  8. Java 用反射设置对象的属性值
  9. mysql拼装字段_Mysql 实现字段拼接的三个函数
  10. C#爬虫项目:SWorld阅读
  11. HS8145X6华为界面telnet23账号密码重置
  12. 怎么把多个音频合并成一个音频?
  13. JAVA 超详细 将文件夹目录打包为 ZIP 压缩包并下载
  14. 支付宝sdk集成,报系统繁忙 请稍后再试(ALI64)
  15. macOS SwiftUI 进度指示器组件规范之 01 进度指标是什么 Progress Indicators
  16. VR和AR只是入门,真正的元宇宙远不止于此
  17. 向量的加减(输出重载)
  18. Matlab 主曲率、平均曲率、高斯曲率
  19. opcache 缓存_缓存帽子戏法:Zend Opcache,Etags和查询缓存
  20. 自动化测试工作考核指标

热门文章

  1. 机器学习算法基础——数据特征预处理
  2. 你所知道及不知道的骗贷、中介、欺诈团伙是怎么样的
  3. 引擎讲解2--主要是MyISAM和InnoDB的区别
  4. 德勤:95%的受访公司将在2019年投资区块链
  5. Visual Studio 2013开发 mini-filter driver step by step (4) - 获取文件名
  6. Spring Boot - 自动配置实现原理
  7. IDEA-使用IDEA创建maven多模块父子工程
  8. Go语言线程与协程之间的关系之GMP模型
  9. arm-linux 交叉编译后程序,ARM交叉编译下,应用程序实践
  10. 为什么是get()和set()方法?