线程调度(Java Android)

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。
未经允许不得转载

目录

  • 一、导读
  • 二、概览
    • 2.1、线程的属性
  • 三、线程的调度
    • 3.1 Java内存模型
    • 3.2 高速缓存
    • 3.3 Java 线程调度机制
    • 3.4 Android线程调度
  • 四、 推荐阅读

在这里插入图片描述

一、导读

我们继续总结学习基础知识,温故知新。

我们在前面讲过
【线程相关基础知识】,本文在此基础上,讲述Android线程调度的相关知识。

二、概览

线程优化是性能优化的一个重点,使用不当的话也会有很大的影响,所以我们需要清楚线程调度原理。
通过基础知识,我们知道任意时刻,只有一个线程占用CPU,处于运行状态,其他的现场处于等待状态,即使是多线程,也是如此,区别就
在于多线程并发是多个线程轮流获取CPU使用权(CPU时间片轮转机制)。

2.1、线程的属性

在日志中,我们经常可以看到这样的信息 com.xxx#RenderThread(119111), 这里面就有线程的名字及编号(id)。
线程有id、名字、类别以及优先级四个属性,我们分别列一下:

  • 编号
    线程的编号(id)用于标识不同的线程,每条线程拥有不同的编号;
    这个id不能作为线程唯一标识,某个编号的线程运行结束后,该编号可能被后续创建的线程使用,因此编号不适合用作唯一标识,编号是只读属性,不能修改;

  • 名字
    每个线程都有自己的名字(name),名字的默认值是 Thread-线程编号,比如 Thread-0 ;
    除了默认值,我们也可以给线程设置名字,以我们自己的方式去区分每一条线程;
    作用:给线程设置名字可以让我们在某条线程出现问题时,用该线程的名字快速定位出问题的地方

  • 类别
    线程的类别(daemon)分为守护线程和用户线程,我们可以通过 setDaemon(true) 把线程设置为守护线程;

  • 优先级
    线程的优先级(Priority)用于表示应用希望优先运行哪个线程,线程调度器会根据这个值来决定优先运行哪个线程;

具体可参考【线程相关基础知识】

三、线程的调度

我们先来了解一些相关概念

3.1 Java内存模型

【jvm 堆、栈、方法区 & java 内存模型】

在多线程场景下,CPU会出现缓存一致性问题,处理器重新排序问题,

为了解决这个问题,制定了计算机内存模型。(原子性、可见性、有序性)
即是Java语言对这个操作规范的遵循,

JMM规定了所有的变量都存储在主存中,每个线程都有自己的工作区,
线程将使用到的变量从主存中复制一份到自己的工作区,线程对变量的所有操作(读取、赋值等)都必须在工作区,
不同的线程也无法直接访问对方工作区,线程之间的消息传递都需要通过主存来完成。
可以把这里主存类比成计算机内存模型中的主存,工作区类比成计算机内存模型中的高速缓存。

在这里插入图片描述

3.2 高速缓存

处理器的处理能力要远胜于主内存(DRAM)的访问速率,;
为了弥补处理器与主内存之间的差距,硬件设计者在主内存与处理器之间加入了高速缓存(Cache);

CPU 高速缓存是内置于 CPU(中央处理器)或位于处理器芯片上的小型快速内存区域。CPU 高速缓存存储主内存中经常使用的数据和指令,以减少 CPU 为这些信息访问主内存的次数

高速缓存相当于是一个由硬件实现的容量极小的散列表,这个散列表的 key 是一个对象的内存地址,value 可以是内存数据的副本,也可以是准备写入内存的数据;

3.3 Java 线程调度机制

1、 在任意时刻,CPU 只能执行一条机器指令,每个线程只有获取到 CPU 的使用权后,才可以执行指令;
也就是在任意时刻,只有一个线程占用 CPU,处于运行的状态;

2、 多线程并发运行实际上是指多个线程轮流获取 CPU 使用权,分别执行各自的任务;

3、 线程的调度由 JVM 负责,线程的调度是按照特定的机制为多个线程分配 CPU 的使用权;

线程调度模型分为两类:分时调度模型和抢占式调度模型;

  • 分时调度模型
    分时调度模型是让所有线程轮流获取 CPU 使用权,并且平均分配每个线程占用 CPU 的时间片;

  • 抢占式调度模型
    让优先级高的线程占用 CPU,如果线程的优先级都一样,那就随机选择一个线程,并让该线程占用 CPU;

也就是如果我们同时启动多个线程,并不能保证它们能轮流获取到均等的时间片;
如果我们的程序想干预线程的调度过程,最简单的办法就是给每个线程设定一个优先级;

多线程是不安全的,具体参考线程的原子性、可见性、有序性及线程安全

3.4 Android线程调度

Android是基于java开发的,但是又有所改动,线程调度也是有所区别的。

Android线程调度有两个决定因素:

  1. Android应用程序线程优先级
    定义在android.os.Process类中,跟java线程优先级一样,值越小优先级越高,

    /**
     * Standard priority of application threads.
     * Use with {@link #setThreadPriority(int)} and
     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
     * {@link java.lang.Thread} class.
     */
    public static final int THREAD_PRIORITY_DEFAULT = 0;
    
    
    /**
     * Standard priority background threads.  This gives your thread a slightly
     * lower than normal priority, so that it will have less chance of impacting
     * the responsiveness of the user interface.
     * Use with {@link #setThreadPriority(int)} and
     * {@link #setThreadPriority(int, int)}, <b>not</b> with the normal
     * {@link java.lang.Thread} class.
     */
    public static final int THREAD_PRIORITY_BACKGROUND = 10;

我们可以在代码中直接定义线程的优先级,如:

    thread.setPriority(android.os.Process.THREAD_PRIORITY_DEFAULT);
  1. cgroup
    android中还定义了一种更严格的群组调度策略,了解linux的同学都清楚,
    Linux的cgroup(Control Group)是一种内核特性,用于对进程组进行资源限制、优先级管理和统计等操作。
    cgroup可以将一组相关的进程组织在一起,并对它们施加各种资源控制策略,以确保系统资源的有效分配和管理。

Android就是借用了这种特性的思想,我们简单理解为将进程进行了分组,比如后台进程组,将后台进程归为一个组,这个组里面的
线程在cpu忙的时候,只有比较小的概率能获取到cpu。

这种前台和后台分开执行策略,即允许后台线程执行任务,保证前台线程可以获取更多的CPU,不会对前台现场造成很大的影响,极大概率的减少卡顿。

下面的线程会移到后台group

  • 优先级低的线程;
  • 不在前台运行的线程

总结一下:
1、线程不是越多越好,太多反而影响效率,大家可参考一下:
线程切换开销
2、另外在设置优先级的时候要酌情一下,并不是都设置最高,最好根据业务情况及工作量来。
3、现场具有继承性,如A线程中启动B线程,则B线程的优先级跟A一样。

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

未经允许不得转载

ddd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/354640.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP服务器基础认识(复习)

鉴于曾经写过相关文章&#xff0c;这里就不再详细介绍了&#xff0c;关于详细的介绍可以参考我之前的文章 HTTP协议初识中篇-CSDN博客 一个简单的设置套接字的过程&#xff0c;也当成是复习一下下了 代码 #include <iostream> #include <cstdio> #include <…

Redis的数据类型

目录 string 1.编码方式 2.应用场景 3.常用命令 hash 1.编码方式 2.应用场景 3.常用命令 list 1.编码方式 2.应用场景 3.常用命令 set 1.编码方式 2.应用场景 3.常用命令 zset 1.编码方式 2.应用场景 3.常用命令 如何理解Redis的编码方式 embs…

2024三掌柜赠书活动第七期:一本书读懂AIGC:探索AI商业化新时代

目录 前言AI商业化的背景和挑战关于《一本书读懂AIGC&#xff1a;探索AI商业化新时代》编辑推荐内容简介作者简介图书目录书中前言/序言《一本书读懂AIGC&#xff1a;探索AI商业化新时代》全书速览结束语 前言 不用多讲&#xff0c;想必大家也都知道&#xff0c;人工智能在过…

k8s-基础知识(Service,NodePort,CusterIP,无头服务,NameSpace,资源限制)

Node Node 是 Pod 真正运行的主机&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。 Annotations 原文链接 Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象&#xff0c;Annotations 则是用来记录一些附加信息&#xff0c;用来辅助应…

【标定】多源LiDAR传感器标定方法(含C++代码)

提供的代码是一种使用平面提取和匹配以及随后的Ceres Solver库优化转换的LiDAR标定方法的全面实现。这种方法用于对齐多个LiDAR传感器的数据,比如那些安装在车辆或机器人不同位置的传感器,以确保它们生成的点云在同一坐标系统中。 以下是对代码及其实现的标定方法的介绍: 利…

linux虚拟化之kvm(一个200行的arm64虚拟机代码)

一、背景 之前介绍了X86上的一个简易虚拟机&#xff1a; linux虚拟化之kvm&#xff08;一个150行的x86虚拟机代码&#xff09;-CSDN博客 &#xff0c;但作为一名嵌入式开发者&#xff0c;还是需要在ARM64上尝试一番&#xff0c;ARM64上的虚拟化和X86还是有很多差异点&#x…

nosql数据库知识点总结

目录 1、什么是nosql数据库&#xff0c;它包括哪些 文档数据库 建数据 哪一种是最简单的 2、什么是文档数据库 3、创建mongodb时默认会建造三个数据库&#xff0c;是哪三个 4、mongodb支持的数据类型有哪些 5、它的常规语句有哪些 6、副本集和分片集有什么作用 复制 …

​​力扣刷MySQL-第九弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

Spring 事务原理二

该说些什么呢&#xff1f;一连几天&#xff0c;我都沉溺在孤芳自赏的思维中无法自拔。不知道自己为什么会有这种令人不齿的表现&#xff0c;更不知道这颗定时炸弹何时会将人炸的粉身碎骨。好在儒派宗师曾老夫子“吾日三省吾身”的名言警醒了我。遂潜心自省&#xff0c;溯源头以…

20240128-读书带来的影响

我本身不算是一个特别喜欢读书的人&#xff0c;更多的时候其实是为了读书而读书。在坚持每天读了一小时书之后&#xff0c;我发现自身开始慢慢有些变化。是什么时候突然有了这种感悟呢&#xff0c;是最近每周5小时左右的微信读书以及纸质书籍的阅读&#xff0c;让我体会到了读书…

C++爱好者的科目四易错点总结

科目四易错点总结 在科目四考试中&#xff0c;一部分内容是可以通过刷题快速掌握的&#xff0c;一部分内容缺因易混淆而降低我们的准确率&#xff0c;本文主要对后者进行总结&#xff0c;期待大家补充与指正。 注&#xff1a; 本文不是全部的知识点总结处 本文不是权威机构 本文…

【分布式技术专题】「探索高性能远程通信」基于Netty的分布式通信框架实现(附通信协议和代码)(上)

基于Netty的分布式通信框架实现 前提介绍回顾Dubbo分布式通信框架组成元素程序执行流程消息协议设计实现机制ChannelInboundHandlerAdapter自定义事件处理 ChannelOutboundHandlerAdapter 编(解)码处理器编码过程阶段ChannelOutboundHandlerAdapter序列化实现ChannelOutboundHa…

NLP自然语言处理的发展:从初创到人工智能的里程碑

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;人工智能领域中备受关注的重要分支之一。它使得计算机能够理解、解释和使用人类语言。随着技术的不断发展&#xff0c;NLP经历了从初创时期到深度学习时代的巨大演变&#xff0c;推动了互联网产…

【教学类-XX -XX 】20240128名字字卡1.0(15CM正方形手工纸、黑体,说明是某个孩子的第几个名字)

作品展示&#xff1a; 15CM手工纸上一个名字&#xff0c;页眉有这个字是哪一位孩子的第X个名字的说明 背景需求&#xff1a; 去年我制作了中6班孩子的姓名卡片&#xff0c;一张A4纸上6个字&#xff0c;每张卡片大约10CM&#xff09; 【教学类-25-01】20230320 名字卡片绘画游…

使用机器学习算法检测交易中的异常行为

交易中的异常检测意味着识别交易或相关活动中的异常或意外模式。这些模式被称为异常或异常值&#xff0c;明显偏离预期规范&#xff0c;可能表明存在不规则或欺诈行为。 异常检测在各种业务中发挥着至关重要的作用&#xff0c;尤其是那些涉及金融交易、在线活动和安全敏感操作…

IMX6ULL驱动学习——通过总线设备驱动模型点亮野火开发板小灯【参考韦东山老师教程】

参考&#xff1a;【IMX6ULL驱动开发学习】11.驱动设计之面向对象_分层思想&#xff08;学习设备树过渡部分&#xff09;-CSDN博客 韦东山课程&#xff1a;LED模板驱动程序的改造_总线设备驱动模型 我使用的开发板&#xff1a;野火imx6ull pro 欢迎大家一起讨论学习 实现了总线设…

ChatGPT与文心一言:智能回复与语言准确性的较量

在当今数字化时代&#xff0c;随着人们对智能化技术的需求不断增长&#xff0c;智能回复工具也成为了日常生活中不可或缺的一部分。ChatGPT和文心一言作为两个备受瞩目的智能回复工具&#xff0c;在智能回复、语言准确性以及知识库丰富度等方面各有卓越之处。 本文将对这两者进…

JAVA编程语言单词汇总

Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 面向对象程序设计语言和 Java 平台的总称。由 James Gosling和同事们共同研发&#xff0c;并在 1995 年正式推出。后来 Sun 公司被 Oracle &#xff08;甲骨文&#xff09;公司收购&#xff0c;Java 也随之成为 Ora…

算法每日一题: 边权重均等查询 | 公共子祖先

大家好&#xff0c;我是星恒&#xff0c;今天给大家带来的是一道图里面有关公共子祖先的题目&#xff0c;理解起来简单&#xff0c;大家 题目&#xff1a;leetcode 2846 现有一棵由 n 个节点组成的无向树&#xff0c;节点按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n …

【Linux C | 网络编程】详细介绍 “三次握手(建立连接)、四次挥手(终止连接)、TCP状态”

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…