上下文切换
当一个进程中的一个线程由于其时间片用完或者其自身原因被迫或者主动暂停其运行时,另外一个线程可以被操作系统选中占用处理器开始或者继续其运行。这种一个线程被暂停,即被剥夺处理器使用权,另一个线程选中开始或者继续运行的过程就叫:线程上下文切换。
切出: 一个线程被剥夺处理器的使用权而被暂停运行就被称为切出。
切入: 一个线程被操作系统选中或者开始继续其运行就被称为切入。
上下文
切入切出的时候操作系统需要保存和恢复相应的进度信息,即切入切出那一刻相应的线程所执行的任务进行到什么程度。这个进度信息就被称为上下文。
他一般包括通用寄存器的内容和程序计数器的内容。在切出时,操作系统将上下文保存到内存,以便被切出的线程稍后占用处理器继续其运行时能够在此基础上进展。在切入时,操作系统需要就从内存中加载(恢复)被选中线程的上下文,以在之前的基础上继续进展。
上下切换的分类:
- 自发性上下文切换:由于其自身因素导致的切出如:
- Thread.sleep()
- Object.wait()
- Thread.join()
- LockSupport.park()
- 线程的I/O操作
- 等待其他线程持有的锁
- 非自发性上下文切换:由于线程调度器的原因被迫切。
- 时间片用完
- 其他优先级更高的线程需要运行
上下文切换的开销:
- 直接开销
- 操作系统保存和恢复上下文所需的开销,主要是时间开销
- 线程调度器进行线程调度的开销(如按照规则决定哪个线程会占用处理器运行)
- 间接开销
- 处理器高速缓存重新加载的开销
上下文切换存在开销,所以也并不是线程的数量越多越好,它可能导致的上下文开销也越大。所以多线程设计减少上下文切换也是一个重要的考量因素。
线程的活性故障
线程有与资源的稀缺性或者自身的问题和缺陷导致一直处于非RUNNABLE状态,或者线程处于RUNNABLE状态但是其执行的任务却一直无法进展的现象就称为线程活性故障
线程活性故障的几种情况:
- 死锁:线程互相处于等待状态
- 锁死
- 活锁:线程处于RUNNBALE状态,但是任务却丝毫没有进展。
- 饥饿:线程因其无法获得其所需的资源而使得任务无法执行无法进展的现象。
资源争用与调度
排他性资源: 一次只能被一个线程占用的资源被称为:排他性资源
资源争用: 在一个资源占有一个排他性资源进行访问(读写)而未释放其对资源的所有权,其他线程视图访问该资源的情况称为:资源争用。
高并发: 同一时间内处于运行状态的线程数量越多,我们就称并发的程度越高。(相对)
多线程的理想状态是高并发、低争用
资源调度
资源调度 :在多线程申请同一个排他性资源的情况下,决定哪个线程会被授予该资源的独占权,即哪个申请者占有该资源的过程就叫:资源的调度。
资源的持有线程 : 获得资源独占权而又未释放资源独占权的线程。
公平性 : 资源的申请线程是否按照其申请顺序而被授予资源的独占权。