线程调度(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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

继承基本介绍

Java提供了关键字extends&#xff0c;可以让一个类和另一个类建立父子关系。 public class a extends b{ //b为父类&#xff0c;&#xff0c;a为子类} 继承的特点&#xff1a;子类可以继承父类的非私有成员&#xff1b;子类的对象由子类、父类共同完成 使用继承可以减少重复…

【正点原子STM32】STM32基础知识(F1F4F7H7 STM32系统框架、寻址范围、存储器映射的存储器功能划分、寄存器映射)

一、STM32系统框架 1.1、Cortex M内核 & 芯片1.2、F1系统架构1.3、F4系统架构1.4、F7系统架构1.5、H7系统架构 二、STM32的寻址范围&#xff1f; 三、存储器映射 存储器功能划分&#xff08;F1为例&#xff09;STM32F1存储器映射图 四、寄存器映射 寄存器基础知识STM3…

第二百九十回

文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何混合选择多个图片和视频文件"相关的内容&#xff0c;本章回中将介绍如何通过相机获取视频文件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. …

python-自动化篇-办公-文件-加解密

解说 要使⽤Python进⾏⽂件的加密和解密&#xff0c;可以使⽤第三⽅加密库&#xff0c;如cryptography或pycryptodome。 ⼀个基本的⽰例&#xff0c;演⽰如何使⽤cryptography库对⽂件进⾏加密和解密&#xff1a; 安装cryptography库&#xff1a; pip install cryptography⽂…

php函数 二

一 字符串包含 1.1 str_starts_with(string $haystack, string $needle) php8版本中新函数。 检查字符串是否以指定子串开头&#xff0c;区分大小写。返回布尔值。 $haystack待判断的字符串&#xff0c;$needle需要查询的内容。 function test1() {$str "Qwe asd zx…

软考笔记--数据库访问接口

数据库访问接口是指应用程序与数据库之间的连接部分。数据库访问接口的发展&#xff0c;对于数据库技术的发展与应用起到了非常重要的作用&#xff0c;它使应用程序与数据库之间的连接变得简单&#xff0c;使应用系统从一种数据库变换成另一种数据库时的修改工作量大大降低。常…

【Vue3 + Vite】Vite搭建 项目解构 Vue快速学习 第一期

文章目录 Vue3介绍Vue3通过Vite实现工程化&#xff1a;一、Vite创建Vue3工程化项目1.1 ViteVue3项目的创建、启动、停止1.2 ViteVue3项目的目录结构 二、ViteVue3 项目组件(SFC入门)2.1 什么是VUE的组件 ?2.2 什么是.vue文件 ?2.3 工程化vue项目如何组织这些组件? 三、ViteV…

【NodeJS】004- NodeJS的模块化与包管理工具

模块化 1. 介绍 1.1.什么是模块化与模块 ? 将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为 模块化 其中拆分出的 每个文件就是一个模块 ,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用 1.2 什么是模块化项目 ? 编码时是按照模…

23. 集合类

集合 1. 概述2. 分类2.1 单列集合&#xff08;Collection&#xff09;2.2 双列集合&#xff08;Map&#xff09; 单列集合 Collection、List、Set、ArrayList、LinkedList’、Vector、HashSet、TreeSet、LinkedHashSet双列集合 Map、HashTable、HashMap、TreeMap、Properties、…

docker 部署及命令

一、容器概述 1、为什么要用到容器&#xff1f; ①容器可以屏蔽底层操作系统的差异性&#xff0c;让业务应用不管在哪里都是使用容器的环境运行&#xff0c;从而保证开发测试环境与生产环境的一致性 ②容器部署起来非常便捷和迅速&#xff0c;缩短开发测试部署的周期时间 2…

Springboot最佳包结构

目录 概述 无默认package 入口类 包结构 概述 我们在构建Springboot项目的时候&#xff0c;我们可以很灵活的去管理我的们class&#xff0c;以及创建包结构&#xff0c;但是有一些原则我们要牢记在心。 无默认package Springboot中的一些注解例如ComponentScan&#xff…

《Python 简易速速上手小册》第10章:Python 项目实战(基于最新版 Python3.12 编写)

注意&#xff1a;本《Python 简易速速上手小册》 核心目的在于让零基础新手「快速构建 Python 知识体系」 文章目录 <mark >注意&#xff1a;本《Python 简易速速上手小册》<mark >核心目的在于让零基础新手「快速构建 Python 知识体系」 10.1 项目规划和结构10.1…

阅读go语言工具源码系列之gopacket(谷歌出品)----第二集 layers-巧妙的抽象与无聊的协议包

上一集中我们讲到了wpcap.dll的go封装方法&#xff0c;对于linux系统下libpcap的go封装采用的是常用的cgo方式&#xff0c;想了解的可以看看pcap文件夹中的pcap_unix.go。 我们得到了wpcap.dll的go调用&#xff0c;就可以利用它来进行列举所有网络设备&#xff0c;例如以下代码…

知识产权如何转为实缴资本,实操

网上已传疯了&#xff0c;相关部门要求企业注册资本认缴的必须在5年内完成实缴&#xff0c;这一下子引起企业老板们着急了。以前公司注册时&#xff0c;很多老板因为是认缴资本&#xff0c;完全凭脑袋一拍&#xff0c;写上注册资金5000万&#xff0c;有的甚至写上几个小目标。现…

11.Elasticsearch应用(十一)

Elasticsearch应用&#xff08;十一&#xff09; 1.什么是自动补全 现代的搜索引擎&#xff0c;一般都会提供Suggest as you type的功能 帮助用户在输入搜索的过程中&#xff0c;进行自动补全或者纠错。通过协助用户输入更加精准的关键词&#xff0c;提高后续搜索阶段文档的…

【GitHub项目推荐--开源翻译模型】【转载】

开源翻译模型 Seamless M4T 旨在提供高质量的翻译&#xff0c;使来自不同语言的人们能够轻松地通过语音和文本进行交流&#xff0c;支持 101 种语言用于语音输入、96 种文本语言输入/输出、 可以输出 35 种语音语言。 此统一模型支持多个任务&#xff0c;而不依赖于多个单独的…

2024.1.27 寒假训练记录(10)

下午训练赛的榜歪得吓人&#xff0c;来补一下题。 文章目录 CF 1646B Quality vs QuantityCF 1326C Permutation PartitionsCF 1355D Game With ArrayAT ARC99B Snuke NumbersAT exawizards2019C Snuke the WizardCF 1788F XOR, Tree, and Queries CF 1646B Quality vs Quantit…

漏洞原理反射型XSS漏洞

漏洞原理XSS漏洞 1 反射型XSS php基础链接 Web渗透编程语言基础-CSDN博客 正常思维 http://127.0.0.1/websec/day01/xss_reflect.php?name%E6%88%91%E6%98%AF%E8%B0%81 http://127.0.0.1/14_WEBSEC/DAY01/xss_reflect.php?name我是谁 黑客思维 http://127.0.0.1/websec…

centos 离线安装yum

1先找一套相同cpu的虚拟机下载rpm 2 如果新的虚拟机没有yum源就替换 修改yum源-CSDN博客 1.2使用wget下载yum源配置文件 (1)备份本地yum源配置文件 备份命令&#xff1a; mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak(2)下载yum源配置文…

Unity 开发过程中如何优化内存

在开发Unity游戏时&#xff0c;优化内存使用是非常重要的。这不仅可以提高游戏性能&#xff0c;还能保证游戏在各种设备上都能顺利运行。以下是一些关于如何在Unity中优化内存使用的建议&#xff1a; 1. 了解并监控您的内存使用情况&#xff1a;您可以使用Unity的Profiler工具…