Android 中设置线程优先级的正确方式(2种方法)


在 Android 中,有两种常见的设置线程优先级的方式:

  1. 第一种,使用 Thread 类实例的 setPriority 方法,来设置线程优先级。
  2. 第二种,使用 Process 类的 setThreadPriority 方法,来设置线程优先级。

这两种设置线程的优先级,一种是 Java 原生版本,另一种是 Android API 版本。这两种方式是不同的,Android 更推荐使用第二种方式。

使用 Thread 类的 setPriority 方法

使用 Thread 类实例的 setPriority 方法,来设置线程优先级,这种方式来源于 Java,他可以通过 Java 的 Thread 属性来设置线程优先级。

  • setPriority 方法的参数是 Thread 的静态常量:
    /*** The minimum priority that a thread can have.*/public final static int MIN_PRIORITY = 1;/*** The default priority that is assigned to a thread.*/public final static int NORM_PRIORITY = 5;/*** The maximum priority that a thread can have.*/public final static int MAX_PRIORITY = 10;

setPriority 方法修改线程优先级时,参数范围必须在 MIN_PRIORITY 和 MAX_PRIORITY 范围之间,如果超过该范围,将抛出错误。设置成功时,此线程的优先级将设置为指定的参数和该线程的线程组的最大允许优先级中的较小者。

也就是说,用 Thread 实例对象的 setPriority 设置线程优先级,范围为 1~10。

我们来看一个示例:

        Thread thread = new Thread(new Runnable() {@Overridepublic void run() {}});thread.setPriority(Thread.MIN_PRIORITY);thread.start();

使用 Process 类的 setThreadPriority 方法

使用 Process 类(android.os.Process)的 setThreadPriority 方法,来设置线程优先级,这是 Android 推荐的方式。

  • setThreadPriority 的参数:
    //应用程序线程的标准优先级public static final int THREAD_PRIORITY_DEFAULT = 0;//最低可用优先级,仅针对那些真的不想在发生任何其他事情的情况下运行的任务。public static final int THREAD_PRIORITY_LOWEST = 19;//标准后台优先级,优先级略低于正常优先级,它对用户界面的影响非常小。public static final int THREAD_PRIORITY_BACKGROUND = 10;//用户正在进行交互的 UI 线程优先级。当用户在界面之间进行切换时,系统将自动调整应用线程的优先级。该优先级应用程序不能自己设置(也就是代码中不能设置)。public static final int THREAD_PRIORITY_FOREGROUND = -2;//系统显示线程的优先级,该优先级应用也不能自己设置。public static final int THREAD_PRIORITY_DISPLAY = -4;//最重要的显示线程的优先级,用于合成屏幕和检索输入事件。应用程序不能更改为此优先级。public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8;//视频线程的标准优先级。应用程序不能更改为此优先级。public static final int THREAD_PRIORITY_VIDEO = -10;//音频线程的标准优先级。应用程序不能更改为此优先级。public static final int THREAD_PRIORITY_AUDIO = -16;//最重要的音频线程的标准优先级。应用程序不能更改为此优先级。public static final int THREAD_PRIORITY_URGENT_AUDIO = -19;

setThreadPriority 的参数同样是一个 int 值,常量定义在 Process 类中。

使用 Android API 为线程设置优先级也很简单,只需要在线程执行时调用 android.os.Process.setThreadPriority 方法即可。这种在线程运行时进行修改优先级,效果类似 renice。

示例代码:

        Thread thread = new Thread(new Runnable() {@Overridepublic void run() {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);}});thread.start();

Linux 系统的 nice

Linux 中,使用 nice 值来设定一个进程的优先级,系统任务调度器根据 nice 值合理安排调度。而 Android 系统是基于 Linux 内核开发的,它的线程的内部实现,也是基于 Linux 的轻量级进程来实现的。

我们来看 nice 的一些特征:

  • nice 的取值范围为 -20 到 19 差不多对应了 Android API 的线程优先级的取值范围。
  • nice 的值越大,进程的优先级就越低,获得 CPU 调用的机会越少,nice 值越小,进程的优先级则越高,获得 CPU 调用的机会越多。
  • 一个 nice 值为 -20 的进程优先级最高,nice 值为 19 的进程优先级最低。
  • 父进程 fork 出来的子进程继承了父进程的优先级。

在 Android 中,无论通过什么方式设置的线程优先级,其实本质上都是通过 native 层,设置 nice 的值来实现的。

对应关系

MAX_PRIORITY ——> 相当于 android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY。MIN_PRIORITY ——> 相当于 android.os.Process.THREAD_PRIORITY_LOWEST。NORM_PRIORITY ——> 相当于 android.os.Process.THREAD_PRIORITY_DEFAULT。

在 Android 系统中,不建议使用 Java 原生的 API 设置线程优先级,因为 Android 提供的 API 划分的级别更多,更适合在 Android 系统中进行设定细致的优先级。

线程优先级的注意事项

  • Android API 的线程优先级和 Java 原生 API 的优先级是相对独立的

Android API 的线程优先级和 Java 原生 API 的优先级是相对独立的,比如使用 android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) 后,使用 Java 原生 Thread.getPriority() 得到的值不会改变。

  • ANR 信息中的线程优先级

我们在分析 ANR 日志时需要注意,在下面的 ANR 日志信息中,prio=5 中 proi 的值对应的 Java 原生 API 的线程优先级。而 nice=-2 中的 nice 表示的 Android API 版本的线程优先级。

"main" prio=5 tid=1 NATIVE| group="main" sCount=1 dsCount=0 obj=0x41690f18 self=0x4167e650| sysTid=1665 nice=-2 sched=0/0 cgrp=apps handle=1074196899| state=S schedstat=( 0 0 0 ) utm=5764 stm=3654 core=2#00  pc 00022624  /system/lib/libc.so (__futex_syscall3+8)#01  pc 0000f054  /system/lib/libc.so (__pthread_cond_timedwait_relative+48)#02  pc 0000f0b4  /system/lib/libc.so (__pthread_cond_timedwait+64)
  • Java 原生 API 中,值越大,优先级越高;而在 Android 原生 API 中,值越小,优先级越高

一定不要混用了线程优先级设置中的常量,Java 原生 API 中,值越大,优先级越高;而在 Android 原生 API 中,值越小,优先级越高。误用了就会出现错误。

总结


  1. 在 Android 中,有两种常见的设置线程优先级的方式:第一种,使用 Thread 类实例的 setPriority 方法,来设置线程优先级。第二种,使用 Process 类的 setThreadPriority 方法,来设置线程优先级。
  2. Java 原生的方法 setPriority 修改线程优先级时,参数范围必须在 MIN_PRIORITY 和 MAX_PRIORITY 范围之间,如果超过该范围,将抛出错误。设置成功时,此线程的优先级将设置为指定的参数和该线程的线程组的最大允许优先级中的较小者。
  3. 使用 Android API 为线程设置优先级也很简单,只需要在线程执行时调用 android.os.Process.setThreadPriority 方法即可。这种在线程运行时进行修改优先级,效果类似 renice。
  4. 在 Android 中,无论通过什么方式设置的线程优先级,其实本质上都是通过 native 层,设置 nice 的值来实现的。
  5. Android API 的线程优先级和 Java 原生 API 的优先级是相对独立的。
  6. ANR 信息中的线程优先级,nice 代表了实际的线程优先级。
  7. 一定不要混用了线程优先级设置中的常量,Java 原生 API 中,值越大,优先级越高;而在 Android 原生 API 中,值越小,优先级越高。误用了就会出现错误。

**PS:更多精彩内容,请查看 --> 《Android 开发》
**PS:更多精彩内容,请查看 --> 《Android 开发》
**PS:更多精彩内容,请查看 --> 《Android 开发》

Android 中设置线程优先级的正确方式(2种方法)相关推荐

  1. android中默认短信,android开发中设置默认短信应用的两种方法

    第一种:利用反射实现的无弹窗设置 public static final String CLASS_SMS_MANAGER = "com.android.internal.telephony ...

  2. android中完全退出当前应用程序的四种方法

    Android程序有很多Activity,比如说主窗口A,调用了子窗口B,如果在B中直接finish(), 接下里显示的是A.在B中如何关闭整个Android应用程序呢?本人总结了几种比较简单的实现方 ...

  3. centos7查看当前cpu运行模式_杂集:centos7中设置服务开机自启的两种方法,欢迎补充...

    前言: 在日常使用linux系统过程中,安装服务后系统不会自动启动服务的.就算手动启动了服务,只是当前生效,一旦服务器重启后,系统不会自动启动这些服务.如果每次重启服务器都要自己手动启动这些服务,一台 ...

  4. android字符串加删除线,android TextView 设置和取消删除线的两种方法

    一.TextView 设置删除线有两种方式: (推荐)方式一: 通过按位或运算符|,将 TextView 原本的 Flags 属性和删除线一块设置.setPaintFlags内会对 TextView ...

  5. android软键盘的回车键,Android中处理软键盘上“回车键”的2种方法

    编程必须有个喜欢总结的习惯, 总结了才能进步,虽然总结的内容不多.但是我要总结. 一方便留着自己以后观看学习,另一方面总结的都是我自己实践过的东西,这样才记得牢. 这里总结单击"回车键&qu ...

  6. 【多线程】线程的引入,创建线程的方式,设置线程名字、获取名字,线程优先级priority,加入休眠的方法,,后台线程,礼让线程,Join,中断线程,某电影院,共有100张票线程流程图,3售票窗口,

    多线程 1.线程的引入 进程: 正在运行的程序,是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内存空间和资源. 线程: 是进程的单个顺序控制流,或者说就是一个单独执行的路径 一个进程如果只 ...

  7. android 线程池 怎么用,android中的线程池 怎么用

    满意答案 qpierq0n5 2016.05.02 采纳率:52%    等级:13 已帮助:8164人 //在Android中实现线程池,首先需要实现一个线程工厂(ThreadFactory)的子类 ...

  8. [转]Android中程序与Service交互的方式——交互方式

    本文转自:http://blog.csdn.net/yihongyuelan/article/details/7216188 上一篇文章:Android中程序与Service交互的方式--综述 简述了 ...

  9. java安卓计时器_如何在android中设置计时器

    通过java.util.Timer和java.util.TimerTask使用计时器的标准Java方法在Android中运行良好,但是你应该知道这个方法创建了一个新线程. 您可以考虑使用非常方便的Ha ...

最新文章

  1. ETSI MEC — 网业协同架构
  2. macbook双网卡路由
  3. 文件上传到ubuntu -- WinSCP 登录ftp服务器
  4. volume 生命周期管理 - 每天5分钟玩转 Docker 容器技术(44)
  5. CentOS 7安装zabbix-2.4.8监控
  6. Maven Scope取值的含义
  7. SharePoint 2013的100个新功能之网站管理(一)
  8. a*算法matlab代码_NSGAII多目标优化算法讲解(附MATLAB代码)
  9. android将拍摄的图片存入sd卡中,Android将图片保存至SD卡上
  10. Excel 使用VBA 使表格的值被修改后填充颜色标注
  11. mysql jdbc 多数据源_springboot jdbc连接多个数据源
  12. 这几个公众号带你看看BAT的工作情况
  13. 大数据分析给企业带来哪些挑战
  14. mysql int做主键_mysql5.5 uuid做主键与int做主键的性能实测
  15. eclipse订制快捷键
  16. 谈谈嵌入式设备用户界面的未来
  17. flex的简介(来自百度百科)
  18. ubuntu linux打印系统时间
  19. 服务器地图不显示图片,传奇小地图不显示怎么办 传奇服务端小地图制作教程...
  20. Python爬虫从入门到精通:(14)验证码识别_Python涛哥

热门文章

  1. MFC绘制独孤信印章
  2. 生活感悟108句话(经典推荐)
  3. 局域网、以太网(标准以太网、工业以太网和实时以太网)与无线局域网
  4. 百度关键词排名怎么提高
  5. 【Educoder python 作业答案】国防科技大学《大学计算机基础》※ 数字音频——儿歌配乐
  6. redis 超时key过期监听
  7. Python有道词典
  8. 当当VP陈立均:当当图书三季度市场份额以45%遥遥领先,四季度开启18周年庆回馈读者阅读盛宴
  9. vue项目打包后,favorite.icon不见了
  10. delphi 经销商 英巴卡迪诺delphi代理