重新认识Android中的线程

线程的几种创建方式

  • new Thread:可复写Thread#run方法。也可以传递Runnable对象,更加灵活。
  • 缺点:缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统的资源导致死机或oom。
 new Thread(new Runnable() {@Overridepublic void run() {}}).start();class MyThread extends Thread{@Overridepublic void run() {super.run();}}new MyThread().start();
  • AsyncTask,轻量级的异步任务工具类,提供任务执行的进度回调给UI线程
  • 场景:需要知晓任务执行的进度,多个任务串行执行
  • 缺点:生命周期和宿主的生命周期不同步,有可能发生内存泄漏(解决方案:将AsyncTask定义为静态内部类)
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;public class ConcurrentTest {public static void test(Context context){class MyAsyncTask extends AsyncTask<String,Integer,String> {@Overrideprotected String doInBackground(String... strings) {for (int i=0;i<10;i++){publishProgress(i*10);}return strings[0];}@Overrideprotected void onPostExecute(String s) {super.onPostExecute(s);Log.e("hzulwy","onPostExecute: "+s);//输出:execute myAsyncTask}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);Log.e("hzulwy","onProgressUpdate: "+values[0]);//输出:10-90}}//适用于需要知道任务执行进度并更新UI的场景MyAsyncTask myAsyncTask = new MyAsyncTask();//默认串行myAsyncTask.execute("execute myAsyncTask");//并发执行myAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,"execute myAsyncTask");//以这种方式提交的任务,所有任务串行执行,即先来后到,但是如果其中有一条任务休眠了,或者执行时间过长,后面的任务将被阻塞AsyncTask.execute(new Runnable() {@Overridepublic void run() {Log.e("hzulwy","run:AsyncTask.execute");}});//适用于并发任务执行AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {@Overridepublic void run() {Log.e("hzulwy","run: THREAD_POOL_EXECUTOR AsyncTask.execute");}});}
}
  • HandlerThread:适用于主线程需要和工作线程通信,适用于持续性任务,比如轮询的场景,所有任务串行执行。
  • 缺点:不会像普通线程一样主动销毁资源,会一直运行着,所以可能会造成内存泄漏 ,需要程序员手动释放
public class ConcurrentTest {private static final int MSG_WHAT_1 = 1;public static void test1(){HandlerThread handlerThread = new HandlerThread("handler-thread");handlerThread.start();handlerThread.quitSafely();//在适当的地方释放资源MyHandler myHandler = new MyHandler(handlerThread.getLooper());myHandler.sendEmptyMessage(MSG_WHAT_1);}static class MyHandler extends Handler{public MyHandler(Looper looper){super(looper);}@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);Log.e("hzulwy","handleMessage: "+msg.what);//输出:1Log.e("hzulwy","handleMessage: "+Thread.currentThread().getName());//输出:handler-thread}}
}
  • IntentService:适用于我们的任务需要跨页面读取任务执行的进度,结果。比如后台上传图片,批量操作数据库等。任务执行完成后,就会自我结束,所以不需要手动stopservice,这是它与service的区分。IntentService包含了service的全部特色。
    class MyIntentService extends IntentService{@Overrideprotected void onHandleIntent(@Nullable Intent intent) {int command = intent.getIntExtra("command",0);//...}context.startService(new Intent());}
  • ThreadPoolExecutor:适用于快速处理大量耗时较短的任务场景(使用最广泛)
        Executors.newCachedThreadPool();//线程可复用线程池Executors.newFixedThreadPool(1);//固定线程数量的线程池Executors.newScheduledThreadPool(1);//指定定时任务的线程池Executors.newSingleThreadExecutor();//线程数量为1的线程池

线程的优先级

        Thread thread = new Thread();thread.start();int ui_proi = Process.getThreadPriority(0);int th_proi = thread.getPriority();//输出结果ui_proi =5;th_proi = 5;
  • 线程的优先级具有继承性,在某线程中创建的线程会继承此线程的优先级。那么我们在UI线程中创建了线程,则线程优先级是和UI线程优先级一样,平等的和UI线程抢占CPU时间片资源。
  • JDK api,限制了新设置的线程的优先级必须为[1~10],优先级priority的值越高,获取cpu时间片的概率越高。UI线程的优先级为5。使用这种方式来设置优先级对线程影响的概率并不大。
  • Android api,可以为线程设置更加精细的优先级(-20~19),优先级的值越低,获取CPU时间片的概率越高。UI线程优先级为-10。推荐使用,影响较大,而且与JDK的方式设置线程优先级互不影响。

Process.setThreadPriority(-10);

线程的几种状态与常用方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//需要保证wait-notify方法的调用顺序,即先wait后notify,否则会有假死的情况private volatile boolean hasNotify = false;final Object object = new Object();public void test2(){Thread thread1 = new Thread(new Runnable1());Thread thread2 = new Thread(new Runnable2());thread1.start();thread2.start();}class Runnable1 implements Runnable{@Overridepublic void run() {Log.e("hzulwy","run:thread1 start");synchronized (object){try {if(!hasNotify){//规避假死情况object.wait(1000);}} catch (InterruptedException e) {e.printStackTrace();}}Log.e("hzulwy","run:thread1 end");}}class Runnable2 implements Runnable{@Overridepublic void run() {Log.e("hzulwy","run:thread2 start");synchronized (object){object.notify();hasNotify = true;}Log.e("hzulwy","run:thread2 end");}}
    public void test2(){//一个线程需要等待另一个线程执行完才能继续的场景Thread thread = new Thread(new Runnable() {@Overridepublic void run() {Log.e("hzulwy","run: 1"+System.currentTimeMillis());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Log.e("hzulwy","run: 2"+System.currentTimeMillis());}});thread.start();try {thread.join();} catch (InterruptedException e) {e.printStackTrace();}//等thread执行完成后才会执行下面的日志Log.e("hzulwy","test: 3"+System.currentTimeMillis());//输出结果://run: 1//run: 2//test: 3}

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

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

相关文章

什么是 API ?

一、API 的定义&#xff1a;数据共享模式定义 4 大种类 作为互联网从业人员&#xff0c;API 这个词我耳朵都听起茧子了&#xff0c;那么 API 究竟是什么呢&#xff1f; API 即应用程序接口&#xff08;API&#xff1a;Application Program Interface&#xff09;&#xff0c;…

Linux(基础IO、文件权限、Makefile)

目录 1、man 手册 1.1 汉化 1.2 具体使用 2、文件权限 2.1 权限理解 2.2 文件详细信息查询 2.3 权限更改 3、常用函数接口 3.1 open 3.2 read 3.3 write 3.4 close 3.5 函数使用示例 4、make与Makefile 4.1 make 与 Makefile区别 4.2 Makefile的编写 5、vim简…

阿里云服务器搭建FRP实现内网穿透-P2P

前言 在了解frp - p2p之前&#xff0c;请先了解阿里云服务器搭建FRP实现内网穿透-转发: 文章地址 1、什么是frp - p2p frp&#xff08;Fast Reverse Proxy&#xff09;是一个开源的反向代理工具&#xff0c;它提供了多种功能&#xff0c;包括端口映射、流量转发和内网穿透等。…

归并排序之从微观看递归

前言 这次&#xff0c;并不是具体讨论归并排序算法&#xff0c;而是利用归并排序算法&#xff0c;探讨一下递归。归并排序的特点在于连续使用了两次递归调用&#xff0c;这次我们将从微观上观察递归全过程&#xff0c;从本质上理解递归&#xff0c;如果能看完&#xff0c;你一…

Wlan——STA上线流程与802.11MAC帧讲解以及报文转发路径

目录 802.11MAC帧基本概念 802.11帧结构 802.11MAC帧的分类 管理帧 控制帧 数据帧 STA接入无线网络流程 信号扫描—管理帧 链路认证—管理帧 用户关联—管理帧 用户上线 不同802.11帧的转发路径 802.11MAC帧基本概念 802.11协议在802家族中的角色位置 其中802.3标…

搭建开发环境-Windows

写C# 的请出去。 然后&#xff0c;Windows 是最好的Linux发行版。搭建开发环境-WSLUbuntu

【Git Bash】简明从零教学

目录 Git 的作用官网介绍简明概要 Git 下载链接Git 的初始配置配置用户初始化本地库 Git 状态查询Git 工作机制本地工作机制远端工作机制 Git 的本地管理操作add 将修改添加至暂存区commit 将暂存区提交至本地仓库日志查询版本穿梭 Git 分支查看分支创建与切换分支跨分支修改与…

Redisi缓存的击穿、穿透、雪崩,介绍一下

缓存击穿 缓存击穿是指在高并发场景下&#xff0c;缓存中的某个 key 失效&#xff0c;此时大量请求同时涌入数据库查询该 key 的数据&#xff0c;导致数据库瞬间压力过大&#xff0c;甚至宕机。缓存击穿的最佳解决方案是使用互斥锁&#xff0c;令只有一个线程可以从数据库中查…

leetcode500. 键盘行

【简单题】 给你一个字符串数组 words &#xff0c;只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。 美式键盘 中&#xff1a; 第一行由字符 "qwertyuiop" 组成。第二行由字符 "asdfghjkl" 组成。第三行由字符 "zxcvbnm&…

React 面试题集锦

目录 如果想要在组件第一次加载后获取该组件的dom元素&#xff0c;应当在以下哪个生命周期中进行 React支持的键盘事件是 使用严格模式&#xff08;Strict Mode&#xff09;优点 React 动态引入组件 当使用ReactDOM.unmountComponentAtNode从DOM中卸载组件时 说一下useS…

Nacos集群

需要与Nginx配合。 这是使用三个Nacos来搭建集群。 创建mysql数据库nacos。 配置Nacos 进入nacos的conf目录&#xff0c;修改配置文件cluster.conf.example&#xff0c;重命名为cluster.conf。 在cluster.conf文件的最后加上&#xff1a; #it is ip #example 127.0.0.1:8…

通俗理解DDPM到Stable Diffusion原理

代码1&#xff1a;stabel diffusion 代码库代码2&#xff1a;diffusers 代码库论文&#xff1a;High-Resolution Image Synthesis with Latent Diffusion Models模型权重&#xff1a;runwayml/stable-diffusion-v1-5 文章目录 1. DDPM的通俗理解1.1 DDPM的目的1.2 扩散过程1.3 …

测试框架pytest教程(6)钩子函数hook开发pytest插件

pytest hook 函数也叫钩子函数&#xff0c;pytest 提供了大量的钩子函数&#xff0c;可以在用例的不同生命周期自动调用。 比如&#xff0c;在测试用例收集阶段&#xff0c;可利用 hook 函数修改测试用例名称的编码。 pytest的hook是基于Python的插件系统实现的&#xff0c;使…

Tokenview再度升级:全新Web3开发者APIs数据服务体验!

Tokenview发布全新版本的区块链APIs和数据服务平台&#xff0c;为开发者打造更强大、更便捷的开发体验&#xff01; 此次升级&#xff0c;我们整合了开发者使用习惯以及Tokenview产品优势。我们深知对于开发者来说&#xff0c;时间是非常宝贵的&#xff0c;因此我们努力提供一…

蚂蚁 SOFAServerless 微服务新架构的探索与实践

赵真灵&#xff08;有济&#xff09; 蚂蚁集团技术专家 Serverless 和微服务领域专家曾负责基于 K8s Deployment 的应用发布运维平台建设、K8s 集群的 Node/pod 多级弹性伸缩与产品建设。当前主要负责应用架构演进和 Serverless 相关工作。同时也是 SOFAArk 社区的开发和维护者…

基于上下文管理器context的timer

文章目录 1. 用 上下文管理器实现计时2. 打印结果 1. 用 上下文管理器实现计时 #!/usr/bin/env python # -*- coding:utf-8 -*- # FileName :MyTimer.py # Time :2023/8/27 13:57 # Author :Jason Zhang import time import mathclass Timer:# 定义开始时间def __ent…

我的数据上传类操作(以webDAV为例)

在登录处进行初始化&#xff1a; 1.读取配置 GModel.ServerSetin JsonToIni.GetClass<ServerSet>(ConfigFiles.ConfigFile);if (!string.IsNullOrWhiteSpace(GModel.ServerSetin.FTPUser)){OPCommon.NetControls.NetworkShareConnect.connectToShare(GModel.ServerSeti…

两款开箱即用的Live2d

目录 背景第一款&#xff1a;开箱即用的Live2d在vue项目中使用html页面使用在线预览依赖文件地址配置相关参数成员属性源码 模型下载 第二款&#xff1a;换装模型超多的Live2d在线预览代码示例源码 模型下载 背景 从第一次使用服务器建站已经三年多了&#xff0c;记得那是在2…

Element-Ui Select下拉框无限滚动调分页接口(自定义指令)

需求: 想要一次加载10条数据&#xff0c;滚动条加载到底部触发下一个十条数据&#xff0c;无限循环直到无数据 一、首先在src下创建一个js文件&#xff0c;完成自定义指令的编写 directives.js import Vue from vueexport default () > {Vue.directive(selectScroll, {bind…

私有IP地址定义、私有IP地址范围(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)

文章目录 私有IP地址定义和范围私有IP地址的使用将局域网中的ip地址设为私有IP地址范围之外的地址&#xff0c;会有什么后果&#xff1f;参考资料 私有IP地址 私有IP地址是在互联网上不被路由的IP地址&#xff0c;专门为组织内部网络&#xff08;如企业内部、学校等&#xff0…