当前位置: 首页 > news >正文

多线程剖析

  什么 是 多线程呢 ?

  • 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程。

  举个 例子:

如果要计算很大的 Fibonacci 数,是不能使用该算法的,因为其中有大量的重复计算。图 27.1 展示了在计算 F6 时所创建的递归过程实例树。其中,对于对于 FIB(6) 的调用会递归地调用 FIB(5) 和 FIB(4) 。而对 FIB(5)的调用又会去调用 FIB(4) 。这两个 FIB(4) 实例返回的结果完全相同( F4 =3 )。由于 FIB 并没有去记住这些结果,因此对于 FIB(4) 的第二次调用重复了第一次调用的工作。

  

   把多线程计算(由一个代表多线程程序的处理器执行的运行时指令集)看做是一个有向无环图 G= ( V, E )是很有帮助的,我们称其为计算 dag ( directed acyclic graph ) 。图 27.2

中给出了一个示例,其中的计算 dag 来自计算 P-FIB(4) 。从概念层面来讲, V 中的顶点都是指令, E 中边则表示指令间的依赖关系, (u,v ) ∈ E 表示指令 u 必须在指令 v 之前执行。为了方便起见,如果一条指令链中不包含任何并行控制语句(没有 spawn 、 sync 以及被 spawn 例程中 return ——显式的 return 语句或者过程执行完后的隐式 return ),我们就把它们组成一组,形成一个 strand ,每个 strand 都表示一条或者多条指令。涉及并行控制的指令不包括在 strand 中,但是会出现在 dag 结构中。例如,如果一个 strand 有两个后继,那么其中之一必须得被spawn 出来,如果一个 strand 有多个前驱,就表示前驱因为一条 sync 语句被合并在一起。因此,一般来说, V 形成了 strand 集合,而有向边集合 E 则表示由并行控制产生的 strand 间的依赖关系。如果 G 中有一个从 strand u 到strand v 的有向路径,那么我们就说这两个 strands 是(逻辑上)串行的。否则就称其为(逻辑上)并行的。

  扎好马步:线程的状态

先来两张图:


线程状态

线程状态转换


各种状态一目了然,值得一提的是"blocked"这个状态:
线程在Running的过程中可能会遇到阻塞(Blocked)情况

  1. 调用join()和sleep()方法,sleep()时间结束或被打断,join()中断,IO完成都会回到Runnable状态,等待JVM的调度。
  2. 调用wait(),使该线程处于等待池(wait blocked pool),直到notify()/notifyAll(),线程被唤醒被放到锁定池(lock blocked pool ),释放同步锁使线程回到可运行状态(Runnable)
  3. 对Running状态的线程加同步锁(Synchronized)使其进入(lock blocked pool ),同步锁被释放进入可运行状态(Runnable)。

此外,在runnable状态的线程是处于被调度的线程,此时的调度顺序是不一定的。Thread类中的yield方法可以让一个running状态的线程转入runnable。

 

  内功心法:每个对象都有的方法(机制)

synchronized, wait, notify 是任何对象都具有的同步工具。让我们先来了解他们


monitor


他们是应用于同步问题的人工线程调度工具。讲其本质,首先就要明确monitor的概念,Java中的每个对象都有一个监视器,来监测并发代码的重入。在非多线程编码时该监视器不发挥作用,反之如果在synchronized 范围内,监视器发挥作用。

wait/notify必须存在于synchronized块中。并且,这三个关键字针对的是同一个监视器(某对象的监视器)。这意味着wait之后,其他线程可以进入同步块执行。

当某代码并不持有监视器的使用权时(如图中5的状态,即脱离同步块)去wait或notify,会抛出java.lang.IllegalMonitorStateException。也包括在synchronized块中去调用另一个对象的wait/notify,因为不同对象的监视器不同,同样会抛出此异常。

  来自国际象棋程序的教训

       我们以一个真实的故事来结束本小节,该故事发生在世界级多线程国际象棋对弈程序 Socrates[81] 的开发期间(时间做了简略)。该程序的原型是在一个具有 32 个处理器的计算机上进行的,但是最终运行在一个具有 512 个处理器的超级计算机上。某天,开发人员对程序进行了一项优化,针对一项重要的在 32 个处理器上基准测试( benchmark ),把其运行时间从 T32 = 65 秒减少到 T’32 =40 秒。然而,开发人员使用关于 work和 span 的性能度量得出结论:在 32 个处理器上更快的优化版本,在 512 个处理器上运行时,实际上比原始版本慢一些。结果,他们放弃了“优化”。

 

       他们的分析方法是这样的。程序的原始版本的 work T1 = 2048 秒, span T = 1 秒。如果把不等式 (27.4)看做是等式, TP = T1 /P+T ,并把它当作在 P 个处理器上的近似运行时间,确实可以得出, T32=2048/32+1 = 65 。如果做了优化, work 变成 T’1 =1024 秒, span 变成 T’ = 8 秒。采用同样的近似方法,有 T’32 =1024/32 + 8=40 。

 

       但是,当在 512 个处理器上进行计算运行时间时,这两个版本的相对速度会发生转换。此时, T512=2048/512+1 = 5 秒, T’512 =1024/512+8 = 10 秒。在 32 个处理器上能够提速程序的优化版本在 512 个处理器上会使得程序慢 2 倍!优化版本的 span 为 8 ,对于 32 个处理器来说,其不是运行时间中的支配项,但是在 512 个处理器时,就变成了支配项,把更多核的优势化为乌有。

 

       这个故事的寓意在于, work 和 span 是一种好的推断性能的方法,而不是一种好的推断运行时间的方法。

 

转载于:https://www.cnblogs.com/kmsfan/p/7225962.html

相关文章:

  • 《中国智慧城市规划与建设》第二版
  • HBase原理和基本概念
  • 移动端单指拖 双值旋转缩放(改动版)
  • 强大的PyTorch:10分钟让你了解深度学习领域新流行的框架
  • 如何修改远程桌面3389端口
  • 17.07.24 Linux 7 文件系统管理
  • python日记----2017.7.25
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • 用quicker-worker.js轻松跑一个大数据遍历
  • HttpClient4.2 Fluent API学习
  • 第二天
  • HCNA
  • AR 与 AI 技术是如何让勇士重回王者的?
  • for循环结构break和continue的用法和区别
  • Java中的关键字
  • 【前端学习】-粗谈选择器
  • Angular6错误 Service: No provider for Renderer2
  • CODING 缺陷管理功能正式开始公测
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Hibernate最全面试题
  • JAVA多线程机制解析-volatilesynchronized
  • JS函数式编程 数组部分风格 ES6版
  • MySQL Access denied for user 'root'@'localhost' 解决方法
  • Python_OOP
  • RxJS: 简单入门
  • 测试开发系类之接口自动化测试
  • 缓存与缓冲
  • 记录:CentOS7.2配置LNMP环境记录
  • 解析带emoji和链接的聊天系统消息
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 力扣(LeetCode)22
  • 码农张的Bug人生 - 初来乍到
  • 前端面试之CSS3新特性
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • linux 淘宝开源监控工具tsar
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # centos7下FFmpeg环境部署记录
  • #includecmath
  • (1)(1.11) SiK Radio v2(一)
  • (2)MFC+openGL单文档框架glFrame
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .Net core 6.0 升8.0
  • .net MySql
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET委托:一个关于C#的睡前故事
  • /etc/sudoer文件配置简析
  • /usr/bin/env: node: No such file or directory
  • ::什么意思
  • @LoadBalanced 和 @RefreshScope 同时使用,负载均衡失效分析
  • [1127]图形打印 sdutOJ
  • [BJDCTF2020]The mystery of ip