造成开销的操作包含:
1. 线程之间的协调(比如:锁、触发信号以及内存同步等)
2. 添加�的上下文切换
3. 线程的创建和销毁
4. 线程的调度

一、对性能的思考

1 性能与可伸缩性

执行速度涉及下面两个指标:
某个指定的任务单元须要“多快”才干处理完毕、计算资源一定的情况下,能完毕“多少”工作。

可伸缩性:
当添加�计算资源时(比如:CPU、内存、存储容器或I/O带宽),程序的吞吐量或者处理能力能对应地添加�。


2 评估各种性能权衡因素
避免不成熟的优化。首先使程序正确,然后再提高执行速度---假设它还执行得不够快。
以測试为基准,不要推測。
提出问题:比如“更快”的含义是什么?提升多少效率?

二、并发三大定律

Amdahl 定律

Gene Amdahl 发如今计算机体系架构设计过程中,某个部件的优化对整个架构的优化和改善是有上限的。这个发现后来成为知名的 Amdahl 定律。

(即使你有10个老婆,也不能一个月把孩子生下来。)



Gustafson 定律

Gustafson如果随着处理器个数的添加�,并行与串行的计算总量也是能够添加�的。Gustafson定律觉得加速系数差点儿跟处理器个数成正比,如果现实情况符合Gustafson定律的如果前提的话,那么软件的性能将能够随着处理个数的添加�而添加�。

(当你有10个老婆,就会要生很多其它的孩子。)



Sun-Ni 定律

充分利用存储空间等计算资源,尽量增大问题规模以产生更好/更精确的解。

(你要设法让每一个老婆都在干活,别让她们闲着。 )


1 演示样例:在各种框架中隐藏的串行部分

2 Amdahl定律的应用


多线程中串行部分是性能提升的瓶颈,比如:
多线程在同一个队列中取出任务,由于须要保证线程安全肯定在队列上加锁,此时就是多线程中串行部分。
多线程一般是处理一些计算,而计算结果可能须要多个线程间进行共享,这也是多线程中串行部分。

三、线程引入的开销

1 上下文切换

大多数通用的处理器中,上下文切换的开销相当于5000~10000个时钟周期(几微妙)
UNIX系统的vmstat、mpstat命令和Windows系统的perfmon工具都能报告上下文切换次数以及和内核中运行时间所占比例等信息。


2 内存同步
在 synchronized 和 volatile 提供的可见性保证中可能会使用一些特殊指令,即内存栅栏(Memory Barrier)。
public String getStoogeNames(){
      Vector<String> stooges = new Vector<String>();
      stooges.add( "Moe" );
      stooges.add( "Larry" );
      stooges.add( "Curly" );
       return stooges.toString();
}

在运行getStoogeNames中,至少将Vector上的锁获取/释放4此,3次add操作与1次toString操作。
JVM会把在一起操作进行合并,可能仅须要获取1次add锁与1次toString锁。


3 堵塞

四、降低锁的竞争

在并发程序中,对可伸缩性的最主要威胁就是独占方式的资源锁。

有3中方式能够减少锁的竞争程度:

1. 降低锁的持有时间。

2. 减少锁的请求频率。

3. 使用带有协调机制的独占锁,这些机制同意更高的并发性。


1 缩小锁的范围(“快进快出”)
假设一个方法中,仅有一个变量是须要多线程间共享的,不须要在方法上加入�synchronized,由于这样会直接锁住整个方法导致其多线程间穿行运行,能够通过方法中仅锁住对共享变量操作的部分来缩小锁的范围提高性能。


2 减小锁的粒度(锁分解)
在一个分装中,假设分别提供的多个方法是分别对多个数据源操作,最严谨的方式是在全部方法上都把当前类作为锁定条件,可是能够通过在每一个数据源上加入�一个独立的锁。


3 锁分段
上一个中是一个类中涉及到多个数据源,假设仅有一个数据源(比如:Map)怎样提高性能?
在数据源上加入�分段锁,比如把map的个数除以4,4份中每一份是用一个单独的锁来锁定。


4 避免热点域
前面提到的一般是针对一个变量、一个数据集合、多个数据集合提高性能的办法,可是有些情况下一个方法内涉及到多个变量或者同一个变量的多个操作,能够通过降低这样的情况出现的次数提升性能。


5 一些替代独占锁的方法
通过放弃独占锁来提升性能。如并发容器,ReadWriteLock,不可变对象以及原子变量。


6 监測CPU的利用率
CPU没有得到充分利用的原因:

. 负载不充足

. I/O密集

. 外部限制

. 锁竞争


7 向对象池说“不”

对象分配操作的开销比同步的开销更低。



五、演示样例:比較Map的性能

六、降低上下文切换的开销

參考资料:

并发三大定律 摘录自《温绍锦 - Java并发程序设计教程》

《Java并发编程实战》第十一章 性能与可伸缩性 读书笔记的更多相关文章

  1. Java并发编程实战 第11章 性能与可伸缩性

    关于性能 性能的衡量标准有很多,如: 服务时间,等待时间用来衡量程序的"运行速度""多快". 吞吐量,生产量用于衡量程序的"处理能力",能够 ...

  2. 《Java并发编程实战》第十章 避免活跃性危急 读书笔记

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/love_world_/article/details/27635333 一.死锁 所谓死锁: 是指两 ...

  3. 《Java并发编程实战》第八章 线程池的使用 读书笔记

    一.在任务与运行策略之间的隐性解耦 有些类型的任务须要明白地指定运行策略,包含: . 依赖性任务.依赖关系对运行策略造成约束.须要注意活跃性问题. 要求线程池足够大,确保任务都能放入. . 使用线程封 ...

  4. Java并发编程实战---第六章:任务执行

    废话开篇 今天开始学习Java并发编程实战,很多大牛都推荐,所以为了能在并发编程的道路上留下点书本上的知识,所以也就有了这篇博文.今天主要学习的是任务执行章节,主要讲了任务执行定义.Executor. ...

  5. Java并发编程实战 第16章 Java内存模型

    什么是内存模型 JMM(Java内存模型)规定了JVM必须遵循一组最小保证,这组保证规定了对变量的写入操作在何时将对其他线程可见. JMM为程序中所有的操作定义了一个偏序关系,称为Happens-Be ...

  6. 【java并发编程实战】第一章笔记

    1.线程安全的定义 当多个线程访问某个类时,不管允许环境采用何种调度方式或者这些线程如何交替执行,这个类都能表现出正确的行为 如果一个类既不包含任何域,也不包含任何对其他类中域的引用.则它一定是无状态 ...

  7. Java并发编程实战 第8章 线程池的使用

    合理的控制线程池的大小: 下面内容来自网络.不过跟作者说的一致.不想自己敲了.留个记录. 要想合理的配置线程池的大小,首先得分析任务的特性,可以从以下几个角度分析: 任务的性质:CPU密集型任务.IO ...

  8. java并发编程实战:第二章----线程安全性

    一个对象是否需要是线程安全的取决于它是否被多个线程访问. 当多个线程访问同一个可变状态量时如果没有使用正确的同步规则,就有可能出错.解决办法: 不在线程之间共享该变量 将状态变量修改为不可变的 在访问 ...

  9. Java并发编程实战 第15章 原子变量和非阻塞同步机制

    非阻塞的同步机制 简单的说,那就是又要实现同步,又不使用锁. 与基于锁的方案相比,非阻塞算法的实现要麻烦的多,但是它的可伸缩性和活跃性上拥有巨大的优势. 实现非阻塞算法的常见方法就是使用volatil ...

随机推荐

  1. JQuery设置与获取RadioButtonList和CheckBoxList的值

    有这样一个问题,要获取ASP.NET控件RadioButtonList的值,首先想到的就是$("#<%=RadioButtonList1.ClientID %>").v ...

  2. BZOJ3258: 秘密任务

    题解: 其实就是一个简单的最小割判断是否唯一解... 可是我写了一上午还没过...T_T 把1-n的最短路上的边提出来做最小割. 然后从s,t分别bfs判断必须在某个割的点.如果有的点没有被bfs到, ...

  3. spring+springMVC+JPA配置详解(使用缓存框架ehcache)

    SpringMVC是越来越火,自己也弄一个Spring+SpringMVC+JPA的简单框架. 1.搭建环境. 1)下载Spring3.1.2的发布包:Hibernate4.1.7的发布包(没有使用h ...

  4. HDU Senior's Gun (水题)

    题意: 给n把枪,m个怪兽,每把枪可消灭1怪兽,并获得能量=枪的攻击力-怪兽的防御力.求如何射杀能获得最多能量?(不必杀光) 思路: 用最大攻击力的枪杀防御力最小的怪兽明显可获得最大能量.如果每把枪都 ...

  5. android——创建camera应用(译)

     只是选择相机部分来翻译.下面是主要内容 有些开发者可能需要Camera的接口,来定制自己程序的外观和特殊功能.创建自定义的Camera界面比使用using an Intent需要编写更多的代码,但是 ...

  6. 错误 1 在应用程序级别之外使用注册为 allowDefinition='

    原文:错误 1 在应用程序级别之外使用注册为 allowDefinition='MachineToApplication' 的节是错误的,银流沙 昨天运行一个.NET网站项目时,出现了以下问题: 在应 ...

  7. Her and his blog

    Tonight, I read localhost8080 and some of her husband m67's blog. I found they are so geek and reall ...

  8. MapReduce 支持的部分数据挖掘算法

    MapReduce 支持的部分数据挖掘算法 MapReduce 能够解决的问题有一个共同特点:任务可以被分解为多个子问题,且这些子问题相对独立,彼此之间不会有牵制,待并行处理完这些子问题后,任务便被解 ...

  9. 【转】Spark是基于内存的分布式计算引擎

    Spark是基于内存的分布式计算引擎,以处理的高效和稳定著称.然而在实际的应用开发过程中,开发者还是会遇到种种问题,其中一大类就是和性能相关.在本文中,笔者将结合自身实践,谈谈如何尽可能地提高应用程序 ...

  10. HW5.31

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...