专栏首页Android开发实战CPU核心数,线程数,时间片轮转机制解读

CPU核心数,线程数,时间片轮转机制解读

点击上方蓝字关注我们,了解更多内容

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重新分配给当前队列的队首进程,同理如此往复。

时间片大小取决于:

  1. 系统对响应时间的要求
  2. 就绪队列中进程的数目
  3. 系统的处理能力

进程调度

采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度程序总是选择就绪队列中的第一个进程,也就是说按照先来先服务原则调度,但一旦进程占用处理机则仅使用一个时间片。在使用一个时间片后,进程还没有完成其运行,它必须释放出处理机给下一个就绪的进程,而被抢占的进程返回到就绪队列的末尾重新排队等待再次运行。

处理器同一个时间只能处理一个任务。处理器在处理多任务的时候,就要看请求的时间顺序,如果时间一致,就要进行预测。挑到一个任务后,需要若干步骤才能做完,这些步骤中有些需要处理器参与,有些不需要(如磁盘控制器的存储过程)。不需要处理器处理的时候,这部分时间就要分配给其他的进程。原来的进程就要处于等待的时间段上。经过周密分配时间,宏观上就象是多个任务一起运行一样,但微观上是有先后的,就是时间片轮换。

实现思想

时间片轮转算法的基本思想是,系统将所有的就绪进程按先来先服务算法的原则,排成一个队列,每次调度时,系统把处理机分配给队列首进程,并让其执行一个时间片。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序根据这个请求停止该进程的运行,将它送到就绪队列的末尾,再把处理机分给就绪队列中新的队列首进程,同时让它也执行一个时间片


Java调度机制

所有的Java虚拟机都有一个线程调度器,用来确定哪个时刻运行哪个线程。主要包含两种:抢占式线程调度器和协作式线程调度器。

  • 抢占式线程调度: 每个线程可能会有自己的优先级,但是优先及并不意味着高优先级的线程一定会被调度,而是由CPU随机的选择,所谓抢占式的线程调度,就是说一个线程在执行自己的任务时,虽然任务还没有执行完,但是CPU会迫使它暂停,让其它线程占有CPU的使用权。
  • 协作式线程调度: 每个线程可以有自己的优先级,但优先级并不意味着高优先级的线程一定会被最先调度,而是由cpu时机选择的,所谓协作式的线程调度,就是说一个线程在执行自己的任务时,不允许被中途打断,一定等当前线程将任务执行完毕后才会释放对cpu的占有,其它线程才可以抢占该cpu。

两者对比:

抢占式线程调度不易发生饥饿现象,不易因为一个线程的问题而影响整个进程的执行,但是其频繁阻塞与调度,会造成系统资源的浪费。协作式的线程调度很容易因为一个线程的问题导致整个进程中其它线程饥饿。

总结:

  • Java在调度机制上采用的是抢占式的线程调度机制。
  • Java线程在运行的过程中多个线程之间是协作式的

本文分享自微信公众号 - 喘口仙氣(gh_db8538619cdd),作者:Anymarvel

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Synchronized深入分析

    Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。

    Anymarvel
  • RxJava for Android学习笔记

    Android工程引入RxJava-android 请引入Rxandroid库: compile 'io.reactivex:rxandroid:1.2.1' ...

    Anymarvel
  • 异步线程大师Handler(源码+图+demo+常见问题)

    Handler 机制 源码+图+常见问题+Demo 详细记录(本文内容略长,但内容较为详细,推荐Android开发者可深入观看.如有问题,欢迎指正)

    Anymarvel
  • 记一次Date引起的线上BUG处理

    在Java8以前,每每操控时间,我们经常使用的类库就是Date,并且会通过SimpleDateFormat类对时间进行格式化。你可知道?Date类是一个可变类,...

    程序员小明
  • python多线程开发

           通过threading.Thread创建一个线程对象,target是目标函数,name可以指定自己喜欢的名字,线程的启动需要借助start方法。线...

    py3study
  • java.util.concurrent 在shorturl项目中的应用

    问题:微博短链项目应用到哪些concurrent包中的类,类的用途是什么?场景是怎样?效果? java.util.concurrent.atomic.Atomi...

    财主刀刀
  • java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?

    死锁、活锁、饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了。 死锁 死锁是多线程中最差的一种情...

    Java技术栈
  • iOS多线程编程之一——NSThread线程管理

    NSTread是iOS中进行多线程开发的一个类,其结构逻辑清晰,使用十分方便,但其封装度和性能不高,线程周期,加锁等需要手动处理。

    珲少
  • 死磕 java同步系列之开篇

    同步系列,这是彤哥想了好久的名字,本来是准备写锁相关的内容,但是java中的CountDownLatch、Semaphore、CyclicBarrier这些类又...

    彤哥
  • 三分钟基础:用户级线程和内核级线程有什么区别?

    网上关于多线程的资料很多,小白很快就把线程的基本概念弄懂了,但关于「用户级线程和内核级线程」的概念,她却怎么也搞不清楚,只好向操作系统基础扎实的小明请教。

    帅地

扫码关注云+社区

领取腾讯云代金券