Java并发编程实战 第11章 性能与可伸缩性
关于性能
性能的衡量标准有很多,如:
服务时间,等待时间用来衡量程序的"运行速度""多快"。
吞吐量,生产量用于衡量程序的"处理能力",能够完成"多少"工作。
多快和多少有时候是互相矛盾的。
关于可伸缩性
可伸缩性:当增加计算资源(CPU 内存 存储 带宽)时,程序的吞吐量或者处理能力能够相应的增加。
评估各种性能权衡的因素
各种性能指标之间权衡,需要考虑的是系统需求和使用场景。
例如,快速排序算法在处理大规模数据集上的执行效率较高,但是小规模数据可能更加适合冒泡排序。
Amdahl定律
定义:在无限增加计算资源的情况下,理论上系统能够达到性能提升比率(最高加速比),局限于程序中可并行组件与串行组件所占的比重。
具体的公式就不列出来了,举个例子,如果系统中必须串行的部分占比为1/2,那么即使你把系统的CPU无限加大,最高也只能达到2倍的加速。如果系统中必须串行的部分占比为1/10,那么即使你把系统的CPU无限加大,最高也只能达到10倍的加速。
Amdahl告诉我们,并不是无限的加大CPU就能够提高性能的。
引入线程的开销
上下文切换
如果在运行的线程数大于CPU数目,那么一个线程的时间片结束,或者被阻塞,将它调出,把时间片交给另外一个线程。就会引起上下文切换。
因为上下文切换带来的负载,操作系统调度器会为每个线程分配一个最小执行时间(如果分配的执行时间还没有上下文切换的时间多,那么岂不是时间都浪费在上下文切换上了)。
一个线程发生阻塞,会放弃它的时间片。所以频繁阻塞会引起过多的上下文切换。
上下文切换就是保存一个线程的状态,加载下一个线程的状态。
内存同步
synchronize和volatile带来的可视性保证可能会使用一些特殊指令,如内存栅栏,它可以刷新缓存,使缓存无效,刷新硬件的写缓存,以及停止执行管道,抑制编译器优化,如重排序。
阻塞
JVM在实现阻塞的时候,有两种方式:
自旋等待,不断地轮询trylock。适用于阻塞时间较短的情况。
使用操作系统挂起线程。适用于阻塞时间较长的情况。
减少锁的竞争
串行操作可以降低可伸缩性。在并行操作内部,可伸缩性最大的威胁就是锁的竞争。
有两个因素可以影响锁的竞争:
- 请求频率。
- 锁定时间
如果两者都很小,那么在锁上发生竞争的机会就比较少。
有3中方式可以减少锁的竞争。
- 锁定时间层面,快进快出
做法就是分解拆分过长的同步代码块。
- 降低线程请求锁的频率
做法就是锁分解和锁分段。跟上面不一样,上面是分解同步代码块。
锁分解:如果一个锁维护了多个相互独立的状态变量。那么可以使用多个锁来维护每个独立的状态变量。
锁分段:使用锁分解技术进一步的将一组数据拆分,然后在拆分后的数据上建立多个锁。
锁分段的案例:
ConcurrentHashMap默认使用包含16个锁的数组,每个锁保护散列通的1/16。
- 不使用独占锁
如使用并发容器,读写锁,不可变对象,原子变量等。
Java并发编程实战 第11章 性能与可伸缩性的更多相关文章
- Java并发编程实战---第六章:任务执行
废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...
- Java并发编程实战 第16章 Java内存模型
什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...
- 【java并发编程实战】第一章笔记
1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...
- Java并发编程实战 第8章 线程池的使用
合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...
- Java并发编程实战 第3章 对象的共享
可见性 可见性是由于java对于多线程处理的内存模型导致的.这似乎是一种失败的设计,但是JVM却能充分的利用多核处理器的强大性能,例如在缺乏同步的情况下,Java内存模型允许编译器对操作顺序进行重排序 ...
- java并发编程实战:第二章----线程安全性
一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问 ...
- Java并发编程实战 第15章 原子变量和非阻塞同步机制
非阻塞的同步机制 简单的说,那就是又要实现同步,又不使用锁. 与基于锁的方案相比,非阻塞算法的实现要麻烦的多,但是它的可伸缩性和活跃性上拥有巨大的优势. 实现非阻塞算法的常见方法就是使用volatil ...
- Java并发编程实战 第10章 避免活跃性危险
死锁 经典的死锁:哲学家进餐问题.5个哲学家 5个筷子 如果没有哲学家都占了一个筷子 互相等待筷子 陷入死锁 数据库设计系统中一般有死锁检测,通过在表示等待关系的有向图中搜索循环来实现. JVM没有死 ...
- Java并发编程实战 第5章 构建基础模块
同步容器类 Vector和HashTable和Collections.synchronizedXXX 都是使用监视器模式实现的. 暂且不考虑性能问题,使用同步容器类要注意: 只能保证单个操作的同步. ...
随机推荐
- python之注释的分类
<1> 单行注释 以#开头,#右边的所有东西当做说明,而不是真正要执行的程序,起辅助说明作用 # 我是注释,可以在里写一些功能说明之类的哦 print('hello world') < ...
- mysql主从复制架构配置
第一个mysql1.下载mysql,解压,移动解压后的目录到指定目录下. 如:mv /usr/local/src/mysql-5.1.. /usr/local/mysql 创建mysql用户, use ...
- Mysql数据库事务的四大特性:
什么是事务? 事务Transaction,是指作为一个基本工作单元执行的一系列SQL语句的操作,要么完全地执行,要么完全地都不执行.为什么要使用事务:保证对数据操作的完整性和准确性.1,原子性:一个事 ...
- FileChannel原理
官方对Channel的解释 (一个用于输入/输出操作的连接.通道表示对实体的开放连接,如硬件设备.文件.网络套接字或能够执行一个或多个不同的输入/输出操作的程序组件,例如读取或写入.) Thankin ...
- mesh重叠闪烁问题
我用正交摄像机做了2d游戏,但是导出spine动画文件是个mesh ,在游戏里有时会出现2个Mesh来回切换显示顺序问题,导致闪烁 查了下并没有发现什么解决方案 后面突然发现只要将摄像机的Y轴偏移一点 ...
- ubuntu系统熄屏无法唤醒
ubuntu系统熄屏无法唤醒 解决办法:重启后,安装laptop-mode-tools工具包. 1.检查是否安装了grep laptop-mode-tools 工具包 $ dpkg -l | grep ...
- 【神经网络与深度学习】深度学习实战——caffe windows 下训练自己的网络模型
1.相关准备 1.1 手写数字数据集 这篇博客上有.jpg格式的图片下载,附带标签信息,有需要的自行下载,博客附带百度云盘下载地址(手写数字.jpg 格式):http://blog.csdn.net/ ...
- Sqlserver 2012附加数据库时出错提示操作系统错误5(拒绝访问)错误5120的解决办法
环境: Win10系统 SQLSERver 2012 情况: 使用混合登陆方式,sa账户密码正确登陆后,附加.mdf文件出现此错误. 尝试解决方法一:使用管理员运行SQLSERver2012,sa账户 ...
- computer(树形dp || 树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- POJ 2253 Frogger(dijkstra 最短路
POJ 2253 Frogger Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fion ...