重新认识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.hqwc.cn/news/87605.html

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

相关文章

W5100S-EVB-PICO进行UDP组播数据回环测试(九)

前言 上一章我们用我们的开发板作为UDP客户端连接服务器进行数据回环测试&#xff0c;那么本章我们进行UDP组播数据回环测试。 什么是UDP组播&#xff1f; 组播是主机间一对多的通讯模式&#xff0c; 组播是一种允许一个或多个组播源发送同一报文到多个接收者的技术。组播源将…

Python爬虫武汉市二手房价格数据采集分析:Linear Regression、XGBoost和LightGBM|代码分享...

全文链接&#xff1a;http://tecdat.cn/?p31958 分析师&#xff1a;Yan Liu 我国有大量的资金都流入了房地产行业&#xff0c;同时与其他行业有着千丝万缕的联系&#xff0c;可以说房地产行业对推动我国深化改革、经济发展、工业化和城市化具有不可磨灭的作用&#xff08;点击…

Docker:Harbor 私有仓库迁移

Harbor 私有仓库迁移 一.私有仓库迁移的介绍 1.为何要对Harbor 私有仓库的迁移 &#xff08;1&#xff09;硬件升级或更换&#xff1a;如果源 Harbor 在旧的硬件设备上运行&#xff0c;并且计划将其迁移到新的硬件设备上&#xff0c;那么需要执行迁移操作。 &#xff08;2&…

如何使用CSS实现一个带有动画效果的进度条?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ HTML 结构&#xff1a;⭐ CSS 样式&#xff1a;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那…

IEC 60068 环境测试介绍及其标准下载

IEC 60068 环境测试介绍及其标准下载 IEC 60068 标准由国际电工委员会 (IEC) 发布&#xff0c;是用于电工产品环境测试的国际标准。 IEC 60068 系列包含有关标准、环境测试程序和测试严重性的基本信息。 IEC 60068 环境测试 制定这一系列标准是为了在特定产品类型&#xff08…

nvm安装electron开发与编译环境

electron总是安装失败&#xff0c;下面说一下配置办法 下载软件 nvm npmmirror 镜像站 安装nvm 首先最好卸载node&#xff0c;不卸载的话&#xff0c;安装nvm会提示是否由其接管&#xff0c;保险起见还是卸载 下载win中的安装包 配置加速节点nvm node_mirror https://npmmi…

css元素定位:通过元素的标签或者元素的id、class属性定位,还不明白的伙计,看这个就行了!

前言 大部分人在使用selenium定位元素时&#xff0c;用的是xpath元素定位方式&#xff0c;因为xpath元素定位方式基本能解决定位的需求。xpath元素定位方式更直观&#xff0c;更好理解一些。 css元素定位方式往往被忽略掉了&#xff0c;其实css元素定位方式也有它的价值&…

Linux上实现分片压缩及解压分片zip压缩包 - 及zip、unzip命令详解

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

visual studio 2022.NET Core 3.1 未显示在目标框架下拉列表中

问题描述 在Visual Studio 2022我已经安装了 .NET core 3.1 并验证可以运行 .NET core 3.1 应用程序&#xff0c;但当创建一个新项目时&#xff0c;目标框架的下拉列表只允许 .NET 6.0和7.0。而我在之前用的 Visual Studio 2019&#xff0c;可以正确地添加 .NET 核心项目。 …

GNS3 在 Linux 上的安装指南

文章目录 GNS3 在 Linux 上的安装指南1. 基于 Ubuntu 的发行版安装 GNS32. 基于 Debian 的安装3. 基于 ArchLinux 的安装4. 从 Pypi 安装 GNS35. 启动 GNS3 服务端GNS3 在 Linux 上的安装指南 大家好,今天我们来聊聊如何在 Linux 上安装 GNS3。GNS3 是一个非常受欢迎的网络模…

【BUG事务内消息发送】事务内消息发送,事务还未结束,消息发送已被消费,查无数据怎么解决?

问题描述 在一个事务内完成插入操作&#xff0c;通过MQ异步通知其他微服务进行事件处理。 由于是在事务内发送&#xff0c;其他服务消费消息&#xff0c;查询数据时还不存在如何解决呢&#xff1f; 解决方案 通过spring-tx包的TransactionSynchronizationManager事务管理器解…

DC电源模块不同的尺寸可以适应实际应用场景

BOSHIDA DC电源模块不同的尺寸可以适应实际应用场景 DC电源模块是现代电子设备的必备部件之一&#xff0c;其可提供稳定的直流电源&#xff0c;保证电子设备正常运行。DC电源模块尺寸的选择直接影响到其适应的应用场景及其性能表现。本文将从尺寸方面分析DC电源模块的适应性&a…