JAVA多线程——上下文切换

多线程中两个必要的开销:线程的创建、上下文切换。下文主要讲的是上下文切换

1. 上下文切换的概念?
上下文切换是指CPU的控制权由运行任务转移到另外一个就绪任务时所发生的事件。
通俗的说,上下文切换就是从当前执行任务切换到另一个任务执行的过程。但是,为了确保下次能从正确的位置继续执行,在切换之前,会保存上一个任务的状态。

2. 上下文切换分类
(1)让步式上下文切换:
       指执行线程主动释放CPU,与锁竞争严重程度成正比,可通过减少锁竞争来避免;
(2)抢占式上下文切换:
       指线程因分配的时间片用尽而被迫放弃CPU或者被其他优先级更高的线程所抢占,
一般由于线程数大于CPU可用核心数引起,可通过调整线程数,适当减少线程数来避免。

3. 上下文发生的情况:

(1)中断处理
       中断分为硬件中断和软件中断,软件中断包括因为IO阻塞、未抢到资源或者用户代码等原因,线程被挂起
(2)多任务处理
       每个程序都有相应的处理时间片,当前任务的时间片用完之后,系统CPU正常调度下一个任务
(3)用户态切换
       这种情况下,上下文切换并非一定发生,只在特定操作系统才会发生上下文切换

4. 进程与线程的区别
(1)线程是进程的一部分。
       进程是表示资源分配的基本单位,又是调度运行的基本单位,是程序执行的一个实例; 
线程是进程中执行运算的最小单位,即执行处理机调度的基本单位,是进程中的一个执行流。 
(2)内存空间不同。
       每一个进程拥有自己独立的内存空间,而线程共享进程的内存空间。

5. 进程上下文切换与线程上下文切换有什么区别?
       进程上下文切换与线程上下文切换最主要的区别就是线程的切换虚拟空间内存是相同的(因为都是属于自己的进程),
但是,进程切换的虚拟空间内存则是不同的。
      线程上下文切换比进程上下文切换快的多。
    
6.  在进行上下文切换时,CPU通过时间片分配算法来循环执行任务,Java中的时间片分配算法有哪些? 
      最简单最常用的就是基于时间片轮转调度算法。时间片轮转调度算法是非常公平的处理机分配方式,可以使就绪队列的每个进程每次仅运行一个时间片。 
      原理:在时间片轮转调度算法中,系统根据先来先服务的原则,将所有的就绪进程排成一个就绪队列,并且每隔一段时间产生一次中断,激活系统中的进程调度程序,完成一次处理机调度,把处理机分配给就绪队列队首进程,让其执行指令。当时间片结束或进程执行结束,系统再次将CPU分配给队首进程。

7. 如何减少上下文切换?
(1)无锁并发编程。
        多线程竞争时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash取模分段,不同的线程处理不同段的数据
(2)CAS算法。
        Java的Atomic包使用CAS算法来更新数据,而不需要加锁
(3)使用最少线程。
        避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态
(4)协程。
        在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

你可能感兴趣的:(微服务技术栈,JAVA多线程)