CPU核心数,线程数
CPU个数、核心数、线程数的关系:
CPU个数:是指物理上,即硬件上的核心数;
核心数:是逻辑上的,简单理解为逻辑上模拟出的核心数;
线程数:是同一时刻设备能并行执行的程序个数,线程数 = cpu个数 * 核数;
CPU线程数和Java多线程概念:
单个CPU线程在同一时刻只能执行单一Java程序,也就是一个线程
单个线程同时只能在单个CPU线程中执行
线程是操作系统最小的调度单位,进程是资源(比如:内存)分配的最小单位
Java中的所有线程在JVM进程中,CPU调度的是进程中的线程
Java多线程并不是由于CPU线程数为多个才称为多线程,当Java线程数大于CPU线程数,操作系统使用时间片机制,采用线程调度算法,频繁的进行线程切换。
IO阻塞时,线程会释放CPU吗?
当线程处于IO操作时,线程是阻塞的,线程由运行状态切换到等待状态。此时CPU会做上下文切换,以便处理其他程序;当IO操作完成后,CPU会收到一个来自硬盘的中断信号,CPU正在执行的线程因此会被打断,回到ready队列。而先前因I/O而waiting的线程随着I/O的完成也再次回到就绪队列,此时CPU可能会选择他执行。
JAVA中并发和并行的概念
并行:指两个或多个事件在同一时刻点发生,CPU同时执行;并发:指两个或多个事件在同一时间段内发生,CPU交替执行;
JAVA线程可以同时在多个核上运行吗?(思考)
操作系统是基于线程调度的,在同一时刻,JAVA进程中不同的线程可能会在不同的核上并行运行。
线程是调度的最小单位,而进程是资源(比如:内存)分配的最小单位。
时间片轮转机制
时间片轮转法(Round-Robin,RR):
根据先进先出原则,排成队列(就绪队列),调度时,将CPU分配给队首进程,让其执行一个时间段(称为:时间片),时间片通常为10-100ms数量级,当执行的时间片用完时,会由计时器发出时钟中断请求,调度程序便据此来停止该进程的执行,并将它排到队列末尾,然后再把CPU重新分配给当前队列的队首进程,同理如此往复。
时间片大小取决于:
系统对响应时间的要求
就绪队列中进程的数目
系统的处理能力
进程调度
采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度程序总是选择就绪队列中的第一个进程,也就是说按照先来先服务原则调度,但一旦进程占用处理机则仅使用一个时间片。在使用一个时间片后,进程还没有完成其运行,它必须释放出处理机给下一个就绪的进程,而被抢占的进程返回到就绪队列的末尾重新排队等待再次运行。
处理器同一个时间只能处理一个任务。处理器在处理多任务的时候,就要看请求的时间顺序,如果时间一致,就要进行预测。挑到一个任务后,需要若干步骤才能做完,这些步骤中有些需要处理器参与,有些不需要(如磁盘控制器的存储过程)。不需要处理器处理的时候,这部分时间就要分配给其他的进程。原来的进程就要处于等待的时间段上。经过周密分配时间,宏观上就象是多个任务一起运行一样,但微观上是有先后的,就是时间片轮换。
实现思想
时间片轮转算法的基本思想是,系统将所有的就绪进程按先来先服务算法的原则,排成一个队列,每次调度时,系统把处理机分配给队列首进程,并让其执行一个时间片。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序根据这个请求停止该进程的运行,将它送到就绪队列的末尾,再把处理机分给就绪队列中新的队列首进程,同时让它也执行一个时间片
Java调度机制
所有的Java虚拟机都有一个线程调度器,用来确定哪个时刻运行哪个线程。主要包含两种:抢占式线程调度器和协作式线程调度器。
抢占式线程调度: 每个线程可能会有自己的优先级,但是优先及并不意味着高优先级的线程一定会被调度,而是由CPU随机的选择,所谓抢占式的线程调度,就是说一个线程在执行自己的任务时,虽然任务还没有执行完,但是CPU会迫使它暂停,让其它线程占有CPU的使用权。
协作式线程调度: 每个线程可以有自己的优先级,但优先级并不意味着高优先级的线程一定会被最先调度,而是由cpu时机选择的,所谓协作式的线程调度,就是说一个线程在执行自己的任务时,不允许被中途打断,一定等当前线程将任务执行完毕后才会释放对cpu的占有,其它线程才可以抢占该cpu。
两者对比:
抢占式线程调度不易发生饥饿现象,不易因为一个线程的问题而影响整个进程的执行,但是其频繁阻塞与调度,会造成系统资源的浪费。协作式的线程调度很容易因为一个线程的问题导致整个进程中其它线程饥饿。
总结:
Java在调度机制上采用的是抢占式的线程调度机制。
Java线程在运行的过程中多个线程之间是协作式的。