第12章 Java内存模型与线程

12.1 概述

12.2 硬件的效率与一致性
《第12章 Java内存模型与线程》

12.3 Java内存模型

12.3.1 主内存与工作内存
《第12章 Java内存模型与线程》

12.3.2 内存间交互操作

12.3.3 对于volatile型变量的特殊规则
第一个保证此变量对所有线程的可见性。
只能保证可见性,在不符合以下两条规则的运算场景中,仍然要通过加锁来保证原子性。
1)运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。
2)变量不需要与其他的状态变量共同参与不变约束

第二个语义是禁止指令重排序优化。

(最好还是别用)

12.3.4 对于long和double型变量的特殊规则
允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次的32位的操作来进行。
实际开发中,不需要声明为volatile,因为商用虚拟机都选择把64位数据的读写操作作为原子操作来对待。

12.3.5 原子性、可见性与有序性
1)原子性
大致可以认为基本数据类型的访问读写是具备原子性的。
在synchronized块之间的操作也具备原子性

2)可见性
可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。
volatile:普通变量与volatile变量的区别是,volatile的特殊规则保证了新值能立即同步到主内存,以及每次使用前立即从主内存刷新。因此,可以说volatile保证了多线程操作时变量的可见性,而普通变量则不能保证这一点。
synchronized和final。

3)有序性
volatile和synchronized。

12.3.6 先行发生原则
时间先后顺序与先行发生原则之间基本没有太大的关系,所以我们衡量并发安全问题的时候不要受到时间顺序的干扰,一切必须以先行发生原则为准。

12.4 Java与线程

12.4.1 线程的实现
线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开,各个线程即可以共享进程资源(内存地址、文件I/O),又可以独立调度(线程是CPU调度的基本单位)。
实现线程的3种方式:
1.使用内核线程实现
2. 使用用户线程实现
3. 使用用户线程加轻量级进程混合实现
4. Java线程的实现
线程模型为基于操作系统原生线程模型来实现。

12.4.2 Java线程调度
两种方式:协同式线程调度和抢占式线程调度。
协同式线程调度,线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另外一个线程上。
抢占式调度的多线程系统,那么每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定。
线程优先级不靠谱,因为线程调度取决于操作系统。

12.4.3 状态转换
1)新建(New):创建后尚未启动的线程处于这种状态
2)运行(Runable):可能正在执行,或者正在等待CPU为它分配执行时间
3)无限期等待(Waiting):要等待被其他线程显示地唤醒。
4)限期等待(Timed Waiting): 在一定时间之后它们会由系统自动唤醒
5)阻塞(Blocked):
阻塞和等待的区别,阻塞在等待着获取到一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生;等待则是在等待一段时间或者唤醒动作的发生。在线程等待进入同步区域的时候,线程将进入这种状态。
6)结束(Terminated):已终止线程的线程状态,线程已经结束执行。
《第12章 Java内存模型与线程》

12.5 本章小结

    原文作者:java内存模型
    原文地址: https://blog.csdn.net/u010819416/article/details/80637706
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞