Java多线程编程实战指南(核心篇)读书笔记(五)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客)
博主准备恶补一番Java高并发编程相关知识,接下来将阅读该书,并且进行比较详细的总结,好记性不如烂笔头,加油。
Java多线程编程实战指南(核心篇)读书笔记(五),主要记录该书第9章和第11/12章的基本概念等知识,欢迎关注本博客。
目录:
- Java异步编程
- 同步计算与异步计算
- 同步和异步的区别:
- 同步存在等待,异步执行不存在等待
- eg. A叫B去吃饭吧,A等着和B一起去,就是同步;A说完我们去吃饭吧,自己先走了,这就是异步
- 同步往往意味着阻塞;异步则往往意味着非阻塞
- 理解下同步异步和阻塞非阻塞的关系:
- 同步阻塞:
- 首先执行任务的方式是同步的,其次阻塞意味着同步任务执行结束前,该任务的发起线程并没有在运行(生命周期状态不为Runnable)
- 同步非阻塞:
- 首先执行任务的方式是同步的,其次非阻塞意味着同步任务执行结束前,该任务的发起线程仍然在运行,只不过此时该线程的主要动作是检查相应的任务是否执行结束(通过轮询的检查方式)。
- 异步阻塞和异步非阻塞同样的道理
- 总结:同步和异步指的是线程执行任务的方式;阻塞非阻塞指的是任务的发起线程是否仍然在运行(轮询方式)
- 同步阻塞:
- 同步和异步的优缺点:
- 同步代码简单、直观,但是往往意味着阻塞,限制了系统的吞吐率
- 异步有利于提高系统吞吐率,但是需要更为复杂的代码和更多的资源投入
- 同步和异步的区别:
- Java Executor框架
- 基本概念
- Runnable接口和Callable接口都是对任务处理逻辑的抽象
- Executor接口则是对任务执行进行的抽象
- 使用该框架的好处就是可以解耦任务的提交和任务的具体执行细节
- 将任务提交给Executor接口,则执行方式为同步执行
- 将任务提交给ThreadPoolExecutor接口,则为异步执行
- Executor接口一定程度上缩小了同步编程和异步编程的代码编写方式
- 由于Executor接口的局限性,出现了其子接口ExecutorService接口
- 可以返回相应的Future执行结果
- shutdown和shutdownNow方法
- ThreadPoolExecutor是ExecutorService的默认实现类
- 实用工具类Executors
- 就像Array和Arrays;Collection和Collections的关系一样;带s的为工具类,定义了一堆工具方法
- 定义了返回线程池的方法:
- newCachedThreadPool()
- newFixedThreadPool()
- newSingleThreadExecutor()
- 异步任务的批量执行:CompletionService
- Future接口能够方便地获取异步任务的处理结果
- CompletionService则可以实现一次性提交一批异步任务并获取这些任务的处理结果
- 计划任务:Scheduled Task
- 有些情况下,我们需要事先提交一个任务,这个任务并不是立即被执行的,而是需要在指定的时间或者周期性地被执行
- 典型的计划任务有:清理系统的来及数据、系统监控和数据备份等。
- ScheduledExecutorService接口是ExecutorService的子接口
- ScheduledExecutorService接口的默认实现类是ScheduledThreadPoolExecutor
- ScheduledThreadPoolExecutor类是ThreadPoolExecutor的子类
- 基本概念
- 同步计算与异步计算
- 多线程编程的硬件基础与Java内存模型
- 填补处理器与内存之间的鸿沟:高速缓存
- 由来:
- 现代处理器处理能力提升飞快,内存DRAM访问速率提升有限
- 主内存执行一次内存读、写操作所需的时间,可能足够处理器执行上百条的指令
- 为了弥补差距,硬件设计者在主内存和处理器之间引入了高速缓存(Cache)
- 高速缓存是一种存取速率远比主内存大而容量远比主内存小的存储部件,每个处理器都有其高速缓存。
- 由来:
- Java同步机制与内存屏障
- 内存屏障:对一类指令的称呼,该指令可以禁止重排序
- volatile关键字的实现:
- 有序性的保证机制:
- Java虚拟机(JIT编译器)在volatile变量读操作之后插入一个获取屏障,保证这个volatile变量读操作先于该屏障之后的任何读写操作被提交
- 在volatile变量写操作之前插入一个释放屏障,保证该屏障之前的任何读写操作都先于这个volatile变量的写操作被提交
- 有序性的保证机制:
- synchronized关键字的实现:
- synchronized对原子性的保证:
- JIT编译器会在monitorenter(用于申请锁的字节码指令)对应的指令后临界区开始前的地方插入一个获取屏障。
- Java虚拟机会在临界区结束后monitorexit(用于释放锁的字节码指令)对应的指令前的地方插入一个释放屏障。
- 获取屏障和释放屏障一起保证了临界区内的任何读写操作都无法被重排序到临界区之外,再加上锁的排他性,使得临界区内的操作具有原子性
- 对有序性的保证:
- 同volatile机制
- synchronized对原子性的保证:
- 内存屏障的缺点:
- 内存屏障可以禁止指令重排序,代价是会阻止编译器、处理器做一些性能优化
- 内存屏障还会导致冲刷缓存器和清空无效队列,比较耗时
- Java内存模型:JMM(Java Memory Model)
- 内存模型,从以下三个方面开解答线程安全问题:
- 原子性问题
- 针对实例变量、静态变量的读写操作,哪些是具备原子性的,哪些可能不具备原子性?
- 可见性问题
- 一个线程对实例变量和静态变量进行的更新在什么情况下能够被其它线程所读取?
- 有序性问题
- 一个线程对多个实例变量、静态变量进行的更新在什么情况下在其它线程看来可以是乱序的(即感知顺序与程序顺序不同)?
- 原子性问题
- JMM规定:
- 对于long/double型以外的数据类型以及引用类型的共享变量进行读、写操作都具有原子性
- 对于volatile修饰的long/double型变量读、写操作也具有原子性
- 可见性和有序性问题:
- happen(s)-before关系
- JMM定义了一些happens-before关系的规则:
- 程序顺序规则
- 一个线程中按照动作的先后顺序
- happens-before关系与时间上的先后关系并无必然的联系
- 内部锁规则
- volatile变量规则
- 对一个volatile变量的写操作happens-before后续每一个针对该变量的读、写操作
- 线程启动规则
- 调用该线程的start方法happens-before该线程中的任何一个动作
- 线程结束规则
- 一个线程中的任何一个动作都happens-before该线程的join方法的执行线程在join方法返回之后所执行的任意一个动作
- 程序顺序规则
- 内存模型,从以下三个方面开解答线程安全问题:
- 填补处理器与内存之间的鸿沟:高速缓存
- Java多线程程序的性能调优
- Java虚拟机对内部锁的优化
- 优化主要包括:锁消除、锁粗化、偏向锁以及适应性锁
- 锁消除:
- JIT编译器借助一种逃逸分析的技术来判断同步块所使用的锁对象是否只能够被一个线程访问而没有被发布到其他线程
- 即,如果可以,则不使用锁
- 锁粗化:
- 合并为一个大的同步块,避免了一个线程的反复申请、释放同一个锁导致的开销;
- 可能会导致一个线程持有锁的时间变长
- 偏向锁:
- 大多数锁并没有被争用,并且这些锁在其整个生命周期内至多只会被一个线程持有
- 适应性锁:
- 即自旋锁,不暂停线程,而是执行一段无意义的代码;适合大多数线程对该锁的持有时间比较短的场景
- 锁(内部锁和显式锁)的开销:
- 上下文切换与线程调度开销
- 内存同步、编译器优化受限的开销限制可伸缩性
- 优化锁的思路:
- 不使用锁,或者降低锁的争用程度
- 减少锁被持有的时间
- 减小临界区的长度
- 降低锁的申请频率
- 降低锁的粒度
- 锁拆分技术
- 锁分段技术
- ConcurrentHashMap就是采用分段锁搞定的,
- 降低锁的粒度
- Java虚拟机对内部锁的优化
如果对你有帮助,记得点赞哦~欢迎大家关注我的博客,我会持续更新后续章节学习笔记,可以进群366533258一起交流学习哦~
本群给大家提供一个学习交流的平台,内设菜鸟Java管理员一枚、精通算法的金牌讲师一枚、Android管理员一枚、蓝牙BlueTooth管理员一枚、Web前端管理一枚以及C#管理一枚。欢迎大家进来交流技术。
Java多线程编程实战指南(核心篇)读书笔记(五)的更多相关文章
- Java多线程编程实战指南 核心篇 读书笔记
锁 volatile CAS final static 原子性保障 具备 具备 具备 不涉及 不涉及 可见性保障 具备 具备 不具备 不具备 具备① 有序性保证 具备 具备 不涉及 具备 具备② 上下 ...
- 《Java多线程编程实战指南+设计模式篇》笔记
线程的监视:工具:jvisualvm.exe 命令:jstack PID 原子性: volatile关键字: 显示锁:人为实现的程序员可控制的锁,包括synchronized和Lock下的实现类: 线 ...
- Java多线程编程实战指南(核心篇)读书笔记(四)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...
- Java多线程编程实战指南(核心篇)读书笔记(三)
(尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番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多线程编程实战指南 设计模式 读书笔记
线程设计模式在按其有助于解决的多线程编程相关的问题可粗略分类如下. 不使用锁的情况下保证线程安全: Immutable Object(不可变对象)模式.Thread Specific Storage( ...
- 学习笔记《Java多线程编程实战指南》三
3.1串行.并发与并行 1.串行:一件事做完接着做下一件事. 2.并发:几件事情交替进行,统筹资源. 3.并行:几件事情同时进行,齐头并进,各自运行直到结束. 多线程编程的实质就是将任务处理方式由串行 ...
随机推荐
- TypeScript 3.3来了!快看看有什么新功能
翻译:疯狂的技术宅原文:https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript 本文首发微信公众号:jingchen ...
- 安卓Android第三方登录-QQ登录
要实现QQ第三方登录,其实只需要一个封装类:QQLoginManager 几乎 三行代码 就实现QQ登录功能 这里先给出Github开源项目地址,项目下有详细的使用说明 下面就开始详细说一说怎么实 ...
- 20145329 《JAVA程序设计》实验三总结
实验日期:2016.4.12 实验时间:15:30~17:30 实验序号:实验三 实验名称: 敏捷开发与XP实践 实验目的与要求: XP基础 XP核心实践 相关工具 实验内容 1.使用git托管代码 ...
- 20145331实验五 Java网络编程及安全
20145331魏澍琛 实验五 Java网络编程 实验内容 1.用书上的TCP代码,实现服务器与客户端. 2.客户端与服务器连接 3.客户端中输入明文,利用DES算法加密,DES的秘钥用RSA公钥密码 ...
- 20145335郝昊《java程序设计》第1次实验报告
2014535郝昊<java程序设计>实验1实验报告 实验名称 利用java语言实现凯撒密码,并运行测试. 实验内容 用java语言实现凯撒密码,凯撒密码是一种代替的移位密码,它将明文加密 ...
- MR案例:基站相关01
字段解释: product_no:用户手机号: lac_id:用户所在基站: start_time:用户在此基站的开始时间: staytime:用户在此基站的逗留时间. product_no lac_ ...
- Mybatis 通过动态SQL获取序列值
配置文件 <select id="getSeq" parameterType="string" resultType="long" ...
- 转:java 重定向和转发的区别
response.sendredirect("http://www.foo.com/path/error.html"); 重定向和转发有一个重要的不同:当使用转发时,JSP容器将使 ...
- webservice的SOAP代理设置
我们的服务器是可以访问的 设置的代理同样也可以访问 接下来设置代理 接着打开TCP窗口 最后来看数据
- 用gitolite搭建git server
在Ubuntu上测试安装一下git server,为后面项目的代码管理做准备.记录流水账如下, 中间关于git 命令的使用说明不做过多解释,需要了解的请google或者直接git help: 我用到了 ...