笔记:Java Language Specification - 章节17- 线程和锁
回答一个问题:多线程场景下,有时一个线程对shared variable的修改可能对另一个线程不可见。那么,何时一个线程对内存的修改才会对另一个线程可见呢?
基本的原则: 如果 读线程 和 写线程 不进行同步,就不能保证可见性
地址:Oracle -- Java Language Specification -- Chapter 17. Threads and Locks 阐述了Java 内存模型下多线程程序的 Semantics
已经有人翻译好了: 深入分析 java 8 编程语言规范:Threads and Locks
14.19. The synchronized Statement
注意: 每个object都有一个monitor lock,这就是内置锁。 synchronized 和 Object.wait() / Object.notify() / Object.notifyAll() 都指的是这把锁。
再明确:每把Mutex 实际上就是 1个open/closed 状态位 + 1个wait-queue (维护着排队等待这把锁而被blocked的threads)
; A mutex may either be open or closed.
; It also contains a queue of threads that are waiting for the mutex to become open
(define-datatype Mutex Mutex?
($a-mutex
(ref@closed? reference?) ; ref to bool
(ref@wait-queue reference?))) ; ref to (listof thread)
所以,obj 和 mutex 就是同义词。
一个object作为内置锁,通过 synchronized 来访问这把锁,而 执行 obj.wait() 会让本线程进入 obj的wait-queue中,obj.notify() 会“发送消息” 给该obj的 wait-queue上的所有threads,
synchronized (o) {...} === lock(o) ; {...} ; unlock(o)
o.wait() === wait(o) // 靠,面向对象的写法看起来有点怪怪的,明明语义是 让本线程去wait(o) ,写成 o.wait() 还容易让人以为是要对 o做点什么呢!
o.notify() === nofity(o)
也就是说 o 的 wait-queue 中存在3种情况的线程:
1. 因为执行 lock(o) 而被阻塞的线程。 这种线程需排队等到锁、才能进入Runnable状态被调度执行。
2. 因为 wait(o) 而加入wait-queue、等待其他线程 notify(o) 的线程,
3. 因为 wait(o, time) 而加入wait-queue、限时等待其他线程 notify(o) 的线程
wait、notify、notifyAll三者的异同: (假设有对象A,线程T)
1. 是Object类的实例方法,且是native方法
2. T调用A的这些方法时必须先拥有A的对象锁,即只能在同步方法或同步块中调用这些方法。否则会抛出IllegalMonitorStateException(是RuntimeException故无需try catch)
3. 调用wait方法并不是立马释放锁,要等同步方法或同步块执行完;
同理,调用notify、notifyAll并不会有线程立马获取到对象锁,需要等调用者所在同步方法或同步块执行完。 4. 可以理解为每个对象有个wait set(等待池)和monitor set(锁池)用来存放线程:
———— wait set中线程等待收到通知信号(notify、notifyAll)、不会竞争获取A的对象锁,
———— monitor set中的线程则竞争对象锁;
T调用A的wait方法则T进入wait set、
T调用notify或notifyAll则wait set中的一个线程(随机选)或所有线程进入monitor set竞争对象锁。
(从这可看出,第一个获得对象锁的wait线程执行完后,若没有继续调用该对象的notify或notifyAll,且monitor set中没有线程,则其他wait线程仍一直等待,即便对该对象锁已经空闲)
笔记:Java Language Specification - 章节17- 线程和锁的更多相关文章
- Java® Language Specification
Java™ Platform, Standard Edition 8 API Specification http://docs.oracle.com/javase/8/docs/api/ The J ...
- 阅读The Java® Language Specification需要知道的英文单词
In any case/on any account 在任何情况下 “Varargs”是“variable number of arguments”的意思.有时候也被简单的称为“variable ...
- 阅读The Java® Language Specification需要知道的术语
Null Pointer Exception,简称NPE 在java中,static final修饰的是常量.根据编译器的不同行为,常量又可分为编译时常量和运行时常量. 举例说明吧 public st ...
- 如何从oracle官网中下载The java language specification(java 语言规范)
第一步: 第二步: 第三步:下面这个图在这个页面的下方,所以你只要一直往下看,直到看到下图的文字为止: 第四步: 第五步: 这样你就可以成功下载该java 语言规范的pdf了. 它直接下载的网址为: ...
- Java 基础【07】线程同步锁的选择
在需要线程同步的时候如何选择合适的线程锁? 例:选择可以存入到常量池当中的对象,String对象等 public class SyncTest { private String name = &quo ...
- Java Language and Virtual Machine Specifications
The Java Language Specification, Java SE 8 Edition HTML | PDF The Java Virtual Machine Specification ...
- Java开发笔记(一百零三)线程间的通信方式
前面介绍了多线程并发之时的资源抢占情况,以及利用同步.加锁.信号量等机制解决资源冲突问题,不过这些机制只适合同一资源的共享分配,并未涉及到某件事由的前因后果.日常生活中,经常存在两个前后关联的事务,像 ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- JAVA语言规范-线程和锁章节之同步、等待和通知
JAVA语言规范:线程和锁 1 同步 java编程语言提供了线程间通信的多种机制.这些方法中最基本的是同步化,此方法是使用监视器实现的.JAVA中每个对象与一个监视器相关联,一个线程可以加锁和解锁监视 ...
随机推荐
- Android Studio总结
课程背景 相信大家对Android Studio已经不陌生了,Android Studio是Google于2013 I/O大会针对Android开发推出的新的开发工具,目前很多开源项目都已经在采用,G ...
- 《Pro Continuous Delivery With Jenkins 2.0》随书笔记
今天同时看完<Pro Continuous Delivery With Jenkins 2.0>, 这书与工作关系很大,但也是快速翻翻. 本书着重点jenkins高可用环境搭建,与gith ...
- 葫芦娃团队对火鸡堂、基于云的胜利冲锋队团队的Beta产品测试报告
Beta项目互测 课程名称:软件工程1916|W(福州大学) 作业要求:Beta阶段团队项目互评 团队名称:葫芦娃队 作业目标:Beta项目互测 一.火鸡堂团队产品测试 1.截图(推荐用动态gif图录 ...
- python3字符串的方法及注释/ 字符串格式化符号含义及格式化符号含义
capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居中,并使用空格填充至长度wid ...
- Hbase与hive集成与对比
HBase与Hive的对比 1.Hive (1) 数据仓库 Hive的本质其实就相当于将HDFS中已经存储的文件在Mysql中做了一个双射关系,以方便使用HQL去管理查询. (2) 用于数据分析.清洗 ...
- Kubernetes部署Spring Boot应用
SpringBoot项目 新建springboot项目 @RestController public class HelloWorldController { @RequestMapping(&quo ...
- matlab-fsolve函数求解多元非线性方程
记录一下代码,方便下次套用模板 options=optimset('MaxFunEvals',1e4,'MaxIter',1e4); [x,fval,exitflag] = fsolve(@(x) m ...
- Debian 安装docker
1 $ curl -fsSL get.docker.com -o get-docker.sh 2 $ sudo sh get-docker.sh --mirror Aliyun
- CF264D - Colorful Stones 题解
题面 官方题解 模拟赛题解 题解概述: 定义符号A~B表示序列A是序列B的子序列,A!~B反之. 设操作序列为I,则有A~I,B!~I,C~I,D!~I. 可得出条件①B!~C且D!~A,所以我们只要 ...
- 【操作系统之六】Linux常用命令之less
一.概念less 工具也是对文件或其它输出进行分页显示的工具,是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more .tail更加的有弹性.在 more 的时候,我们并没有 ...