学习笔记《Java多线程编程实战指南》三
3.1串行、并发与并行
1.串行:一件事做完接着做下一件事。
2.并发:几件事情交替进行,统筹资源。
3.并行:几件事情同时进行,齐头并进,各自运行直到结束。
多线程编程的实质就是将任务处理方式由串行改为并发,即实现并发化。
3.2竞态
状态变量:即类的实例变量、静态变量。可以被多个线程共享,也被称为共享变量。
共享变量: “可以”(不代表一定)被多个线程共同访问的变量。
多线程编程中对于同样的输入,程序输出的结果的正确性与时间有关的现象就被称为竞态,也就是说计算结果时而正确时而错误。
竞态常常是因为读取脏数据问题,即读取到一个过时的数据、丢失更新问题。二维表分析法是分析竞态问题的一种简单而有效的方法。
3.3竞态的模式与竞态产生的条件
3.3.1竞态的两种模式
read-modify-write(读-改-写) 和 check-then-act(监测而后行动)
if(sequence >= 999){ // 监测而后行动
sequence = 0;
} else {
sequence++; // 读-改-写
}
3.3.2竞态产生的条件
访问(读取、更新)同一组共享变量的多个线程所执行的操作相互交错。
3.3.3 消除竞态
1.将共享变量改为局部变量。
2.在访问共享变量的方法上加锁,synchronize关键字,使得该方法涉及的共享变量在任意时刻只能有一个线程访问。
3.4线程安全性
线程安全:如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能正常运行。不会导致竞态
非线程安全: 如果一个类在单线程环境下运行正常而在多线程环境下无法正常运行。会导致竞态,例如ArrayList、HashMap和SimpleDateFormat
3.4.1原子性
1.指访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束,要么尚未发生,即其他线程不会“看到”该操作执行了部分的中间效果。
2.实现原子性的方式有加锁synchronize关键字(软件锁),还有CAS指令(硬件锁)。
3.long型和double型以外的任何类型的变量的写操作都是原子操作。包括byte、short、int、char、boolean、float、String。为了保障long/double写操作的原子性,需要加volatile关键字修饰。 4.原子操作+原子操作 != 原子操作。
3.4.2可见性
可见性就是指一个线程对共享变量的更新的结果,对于读取相应共享变量的线程而言是否可见(能否读取到更新后的结果)的问题。
单处理器系统实现的多线程编程也可能出现可见性问题。
父线程在子线程启动之前对共享变量的更新对子线程的可见性是有保障的。父线程在子线程启动之后对共享变量的更新对子线程的可见性是没有保障的。
可见性的保障是通过使更新共享变量的处理器执行冲刷处理器缓存的动作,并使读取共享变量的处理器执行刷新处理器缓存的动作。java中通过对共享变量加volatile关键字修饰来保障可见性。
3.4.3有序性
感知顺序和源代码顺序一致,即有序性。volatile关键字、synchronized关键字都能够实现有序性。
可见性是有序性的基础。有序性影响可见性。
3.5上下文切换
一个线程被暂停,即被剥夺处理器的使用权,另外一个线程被选中开始或者继续运行的过程就叫做线程上下文切换。
切出:一个线程被剥夺处理器的使用权而被暂停运行。
切入:一个线程被操作系统选中占用处理器开始或者继续其运行。
上下文:切出和切入的时候操作系统需要保存和恢复相应线程的进度信息,这个进度信息就被称为上下文。
多线程编程想必单线程编程来说,意味着更多的上下文切换,因此,多线程编程不一定比单线程的计算效率更高。
3.5.1上下文切换的分类和具体诱因
自发性上下文切换:Thread.sleep(); Object.wait();Thread.yield();Thread.join();LockSupport.park();I/O操作或者等待其他线程持有的锁。
非自发性上写文切换:时间片用完了;线程优先级更高的线程需要被运行;java虚拟机的垃圾回收动作。
3.6线程的活性故障
线程活性故障:由于资源稀缺性或者程序自身的原因和缺陷导致线程一直处于非RUNNABLE状态,或者线程虽然处于RUNNABLE状态但是其要执行的任务却一直无法进展的现象叫做线程活性故障。
死锁:例如:一个线程X持有资源A的时候等待另一个线程释放资源B。而另一个线程Y在持有资源B的时候却等待线程X释放资源A。死锁的外在表现就是当事线程的生命周期状态永远处于非RUNNABLE状态。
锁死:例如:一个线程X始终在等待资源或者锁而一直处于非RUNNABLE状态。
活锁:例如:一个线程在执行时,一直无法结束而一直处于RUNNABLE状态,并且线程所要执行的任务却丝毫没有进展。即线程可能一直在做无用功。
饥饿:饥饿就是线程因无法获得其所需的资源而使得任务执行无法进展的现象。
3.7资源争用与调度
资源的争用与调度:由于资源的稀缺性或者资源本身的特性,我们往往需要在多个线程间共享同一个资源。
排他性资源:
资源争用:在一个线程占用一个排他性资源进行访问(读、写操作)而未释放其对资源所有权的时候,其他线程试图访问该资源的现象就被称为资源争用。争用是在并发环境下产生的一种现象。
资源调用的一种常见策略就是排队。资源调度器内部维护一个等待队列。通常,被存入等待队列的线程会被暂停,当相应的资源被其持有线程释放时,等待队列中的一个线程会被选中唤醒而再次获得申请自愿的机会。被唤醒的线程如果申请到资源的独占权,那么该线程会从等待队列中移除。
公平的调度策略不允许插队的现象,而非公平的调度策略则允许允许插队的现象。即一个线程释放器资源独占权的时候,等待队列中的一个线程会被唤醒再次申请相应的资源。极端的情况下非公平调度策略可能导致等待队列中的线程永远无法获得其所需的资源,会出现饥饿。
学习笔记《Java多线程编程实战指南》三的更多相关文章
- Java多线程编程实战指南(核心篇)读书笔记(三)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java多线程编程实战指南(核心篇)读书笔记(五)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java多线程编程实战指南(核心篇)读书笔记(四)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java多线程编程实战指南(核心篇)读书笔记(二)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java多线程编程实战指南(核心篇)读书笔记(一)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76422930冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- 《Java多线程编程实战指南(核心篇)》阅读笔记
<Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...
- 学习笔记《Java多线程编程实战指南》二
2.1线程属性 属性 属性类型及用途 只读属性 注意事项 编号(id) long型,标识不同线程 是 不适合用作唯一标识 名称(name) String型,区分不同线程 否 设置名称有助于 ...
- 学习笔记《Java多线程编程实战指南》一
1.1什么是多线程编程 多线程编程就是以线程为基本抽象单位的一种编程范式,和面向对象编程是可以相容的,事实上Java平台中的一个线程就是一个对象.多线程编程不是线程越多越好,就像“和尚挑水”的故事一样 ...
- Java多线程编程实战指南 核心篇 读书笔记
锁 volatile CAS final static 原子性保障 具备 具备 具备 不涉及 不涉及 可见性保障 具备 具备 不具备 不具备 具备① 有序性保证 具备 具备 不涉及 具备 具备② 上下 ...
随机推荐
- Python 验证线程是数据共享的
import os import time from threading import Thread # from multiprocessing import Process #通过对全局变量的修改 ...
- nodejs中的垃圾回收机制
node是基于V8引擎开发的,V8的设计是为浏览器设计的,所以V8的内存相对较少,当然可以通过 node --max-old-space-size=1700 (单位是MB) 或 node --max- ...
- SpringBoot的学习【6.YML 和 Properties 的语法】
1.YML的基本语法 KEY:(空格)value:(空格) 以空格的缩进来表示同一层级.属性和值是大小写敏感的. 2.YML和属性.属性值进行匹配 注解:@ConfigurationPropertie ...
- Classnotfoundexception 与 noClassDelfaultError的区别
ClassNotFoundException 这个异常特别常见,就是class找不到异常,一般的问题就是: 1 调用class的forName方法时,找不到指定的类 2 ClassLoader 中的 ...
- 固态硬盘Ghost安装Windows 10无法引导的问题
机器配置如下: 电脑型号 技嘉 B360M POWER 台式电脑 操作系统 Windows 10 64位 ( DirectX 12 ) 处理器 英特尔 Core i7-8700 @ 3.20GHz 六 ...
- Window 下载Android系统源代码
第一步:使用命令下载manifest文件夹 git clone https://aosp.tuna.tsinghua.edu.cn/ 第二步:进入文件夹,打开default.xml文件并找到自己要下载 ...
- [ 随手记6 ] C/C++ 形参、实参、按值传参、指针传参、引用传参
个人原创: 1. 形参:形式上的参数,一般多在函数声明.函数定义的参数上: 2. 实参:实体参数,有实际的值,在运算上被循环使用的值: 3. 按值传参:按值,就是把实际的值传给函数内部: 4. 指针传 ...
- python 读fnl数据
(1) FNL 数据介绍 FNL((Final Operational Global Analysis)数据是美国国家环境预报中心(NECP)/美国国家大气研究中心(NCAR)提供的全球再分析资料,空 ...
- Java线程池不错的总结博客
ImportNew线程池总结 Java多线程之Executor.ExecutorService.Executors.Callable.Future与FutureTask 线程池,这一篇或许就够了
- CentOS7虚拟机克隆,且成功互ping
第一步:克隆 https://blog.csdn.net/mijichui2153/article/details/80918285 打开VMware,确认已经完成安装配置的CentOS7虚拟机在关闭 ...