回答一个问题:多线程场景下,有时一个线程对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- 线程和锁的更多相关文章

  1. Java® Language Specification

    Java™ Platform, Standard Edition 8 API Specification http://docs.oracle.com/javase/8/docs/api/ The J ...

  2. 阅读The Java® Language Specification需要知道的英文单词

      In any case/on any account  在任何情况下 “Varargs”是“variable number of arguments”的意思.有时候也被简单的称为“variable ...

  3. 阅读The Java® Language Specification需要知道的术语

    Null Pointer Exception,简称NPE 在java中,static final修饰的是常量.根据编译器的不同行为,常量又可分为编译时常量和运行时常量. 举例说明吧 public st ...

  4. 如何从oracle官网中下载The java language specification(java 语言规范)

    第一步: 第二步: 第三步:下面这个图在这个页面的下方,所以你只要一直往下看,直到看到下图的文字为止: 第四步: 第五步: 这样你就可以成功下载该java 语言规范的pdf了. 它直接下载的网址为: ...

  5. Java 基础【07】线程同步锁的选择

    在需要线程同步的时候如何选择合适的线程锁? 例:选择可以存入到常量池当中的对象,String对象等 public class SyncTest { private String name = &quo ...

  6. Java Language and Virtual Machine Specifications

    The Java Language Specification, Java SE 8 Edition HTML | PDF The Java Virtual Machine Specification ...

  7. Java开发笔记(一百零三)线程间的通信方式

    前面介绍了多线程并发之时的资源抢占情况,以及利用同步.加锁.信号量等机制解决资源冲突问题,不过这些机制只适合同一资源的共享分配,并未涉及到某件事由的前因后果.日常生活中,经常存在两个前后关联的事务,像 ...

  8. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  9. JAVA语言规范-线程和锁章节之同步、等待和通知

    JAVA语言规范:线程和锁 1 同步 java编程语言提供了线程间通信的多种机制.这些方法中最基本的是同步化,此方法是使用监视器实现的.JAVA中每个对象与一个监视器相关联,一个线程可以加锁和解锁监视 ...

随机推荐

  1. Nginx Rewrite相关功能-rewrite指令

    Nginx Rewrite相关功能-rewrite指令 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  2. Nacos 1.1.0发布,支持灰度配置和地址服务器模式

    https://nacos.io/zh-cn/blog/nacos%201.1.0.html

  3. PAT 乙级 1038.统计同成绩学生 C++/Java

    题目来源 本题要求读入 N 名学生的成绩,将获得某一给定分数的学生人数输出. 输入格式: 输入在第 1 行给出不超过 1 的正整数 N,即学生总人数.随后一行给出 N 名学生的百分制整数成绩,中间以空 ...

  4. SIFT和SURF特征(草稿)

    (草稿) https://www.cnblogs.com/gavanwanggw/p/7073905.html

  5. scapy 中sniff指定的数据包并打印指定信息

    在理解这篇文章前可以先看看这两篇文章: https://www.cnblogs.com/liyuanhong/p/10925582.html https://www.cnblogs.com/liyua ...

  6. 三块sm865组建RAID0

    介绍 使用三块sm865组件raid0,cpu为6700k,主板为华硕的z170-A 这里使用的是主板自带的raid0,不是win10自带的带区卷 CrystalDiskMark AS SSD Ben ...

  7. 【Mybatis】传入参数 对象+单参

    Integer update( @Param(value="bean") TXNJSTXNDetailTBBean bean, @Param(value="table&q ...

  8. 【Linux】netstat命令

    https://www.cnblogs.com/ftl1012/p/netstat.html这个讲的不错 https://www.linuxprobe.com/netstat-common-metho ...

  9. 第05组 团队Git现场编程实战

    一.组员职责分工 组员 分工 卢欢(组长) 前后端接口设计 严喜 寻找相关资料 张火标 设计并描述界面原型 钟璐英 编写随笔 周华 填写完善文档 古力亚尔·艾山 填写完善文档 张聪 前后端接口设计 池 ...

  10. LeetCode 885. Spiral Matrix III

    原题链接在这里:https://leetcode.com/problems/spiral-matrix-iii/ 题目: On a 2 dimensional grid with R rows and ...