掌握高并发、高可用架构
第二课 并发编程
从本课开始学习并发编程的内容。主要介绍并发编程的基础知识、锁、内存模型、线程池、各种并发容器的使用。
第一节 并发基础
并发编程
并发基础
进程
线程
线程通信
系统、包括操作系统的运行是以CPU为核心的,各种数据操作都是在CPU中进行的。所以要学习并发编程,必须要搞清楚和CPU的关系。
CPU简介
经常说CPU是4核8线程的,这个的意思是4个物理核心
,每个物理核心虚拟出2个虚拟核心,也就是8个虚拟核心
。每个虚拟核心在一个时刻只能运行一个线程。
进程和线程
进程的定义:程序被载入内存并开始准备执行,它就是一个进程,也就是说进程是执行中的程序代码。进程是资源分配和程序调度运行的基本单位。
线程的定义:单个进程中执行每个任务就是一个线程。线程是进程中执行运算的最小单位。
一个线程只能属于一个进程,一个进程可以拥有多个线程。多线程处理就是允许一个进程中在同一时刻执行多个任务(线程)。
对比 | 进程 | 线程 |
---|---|---|
定义 | 进程是程序实体的运行过程,是系统资源分配和调度运行的基本单位 | 线程是进程执行任务的最小调度单位 |
系统开销 | 创建切换开销大,资源要重新分配和回收 | 仅保存少量寄存器的内容,开销小,并且在进程的地址空间执行代码 |
占有资源 | 拥有分配的所有资源 | 基本不占资源,仅有其运行不可少的资源(程序计数器、一组寄存器和栈) |
安全性 | 进程间相互独立 | 线程间共享进程的资源,可以互相通信和影响 |
CPU线程调度
大多数的应用程序为了提高其执行效率,而采用多线程模式。充分利用CPU的核心来实现高效率运行。那是不是最大只能同时开启8个线程呢?如果想开启更多线程,可以吗?CPU内部该如何处理呢?
对于4核8线程的CPU来说,如果只起8个线程,每个虚拟内核都各自执行一个线程,这是最简单的高效率利用方式。但是在实际使用时这是不可能的。首先,计算机硬件必须有操作才能运行,而操作系统启动后在运行过程中必不可少的要执行各种任务;其次,个人运行的程序也是要启动线程来执行各种各样的任务调度。所以,对于一台电脑,不管是个人PC还是服务器,其真正运行的线程肯定是多于CPU的内核数的,那它是如何保证各个任务流畅运行的呢?
这就是CPU的线程调度。采用一定的算法把CPU的使用权合理的分配给线程,使得任务执行。
有两种调度模型,分时调度
和抢占式调度
。
分时调度模型是指让所有的线程轮流获得CPU的使用权,并且平均分配每个线程占用的CPU时间片。
抢占式调度模型是指优先让运行池中优先级最高的线程占用CPU,如果优先级相同,则随机选择一个线程来占用CPU。处于运行中状态的线程会一直运行,直到它不得不放弃CPU。
JVM采用抢占式调度。
一个线程会因为以下原因而放弃CPU:
- JVM使其暂时放弃CPU,转入就绪状态
- 阻塞
- 执行结束
串行、并行和并发
串行:是指多个任务,一个执行完接着一个
并行:每个核心执行一个任务,同一时刻多个任务同时执行
并发:多个任务在单核心上执行,同一时刻只有一个任务,系统不停的切换任务,看起来像是同时执行,实际上是不停的切换
多核下的线程数量选择
对于计算密集型任务,线程数量不宜过多,因为本身任务就是高CPU利用率,线程多的话,会因为上下文切换而浪费资源。对于IO密集型任务,比如磁盘IO和网络IO,因为任务是低CPU利用率,所以可以适当多开线程。
原文地址:https://blog.51cto.com/liusw94/2428642