Java高并发编程:HandlerThread
1. HandlerThread的使用
继承自Thread,在run()方法中,执行了Looper.prepare()和Looper.loop(),和handler结合使用,实现后台轮询线程功能
- start()
- quit()
- getLooper()
public class HandlerThreadActivity extends AppCompatActivity {private TextView mTvServiceInfo;private HandlerThread mCheckMsgThread;private Handler mCheckMsgHandler;private boolean isUpdateInfo;private static final int MSG_UPDATE_INFO = 0x110;//与UI线程相关的handlerprivate Handler mHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_thread_handler);initBackThread();//创建后台线程mTvServiceInfo = (TextView) findViewById(R.id.id_textview);}@Overrideprotected void onResume() {super.onResume();isUpdateInfo = true;//开始查询mCheckMsgHandler.sendEmptyMessage(MSG_UPDATE_INFO);}@Overrideprotected void onPause() {super.onPause();isUpdateInfo = false;//停止查询mCheckMsgHandler.removeMessages(MSG_UPDATE_INFO);}private void initBackThread() {mCheckMsgThread = new HandlerThread("check-message-coming");mCheckMsgThread.start();mCheckMsgHandler = new Handler(mCheckMsgThread.getLooper()) {@Overridepublic void handleMessage(Message msg) {checkForUpdate();if (isUpdateInfo) {mCheckMsgHandler.sendEmptyMessageDelayed(MSG_UPDATE_INFO, 1000);}}};}//模拟从服务器解析数据private void checkForUpdate() {Thread.sleep(1000);//模拟耗时mHandler.post(new Runnable() {@Overridepublic void run() {String result = "msg";mTvServiceInfo.setText(result);}});}@Overrideprotected void onDestroy() {super.onDestroy();mCheckMsgThread.quit();//释放资源}
}
2. HandlerThread源码
Handler的构造,其实就是在Handler中持有一个指向该Looper.mQueue对象,当handler调用sendMessage方法时,其实就是往该mQueue中去插入一个message,然后Looper.loop()就会取出执行
public class HandlerThread extends Thread {int mPriority;int mTid = -1;Looper mLooper;public HandlerThread(String name) {super(name);mPriority = Process.THREAD_PRIORITY_DEFAULT;}public HandlerThread(String name, int priority) {super(name);mPriority = priority;}protected void onLooperPrepared() {}@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}public Looper getLooper() {if (!isAlive()) {return null;}// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {}}}return mLooper;}public boolean quit() {Looper looper = getLooper();if (looper != null) {looper.quit();return true;}return false;}public boolean quitSafely() {Looper looper = getLooper();if (looper != null) {looper.quitSafely();return true;}return false;}public int getThreadId() {return mTid;}
}
我们要在子线程中调用Looper.prepare() 为一个线程开启一个消息循环,默认情况下Android中新诞生的线程是没有开启消息循环的。(主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。) Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 然后通过Looper.loop() 让Looper开始工作,从消息队列里取消息,处理消息。
注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。
3. HandlerThread的特点
HandlerThread将loop转到子线程中处理,说白了就是将分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。
开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。
但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。
HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。
对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。
4. 参考
详解 Android 中的 HandlerThread
Java高并发编程:HandlerThread相关推荐
- Java高并发编程详解系列-Java线程入门
根据自己学的知识加上从各个网站上收集的资料分享一下关于java高并发编程的知识点.对于代码示例会以Maven工程的形式分享到个人的GitHub上面. 首先介绍一下这个系列的东西是什么,这个系列自己 ...
- Java高并发编程 (马士兵老师视频)笔记(一)同步器
本篇主要总结同步器的相关例子:包括synchronized.volatile.原子变量类(AtomicXxx).CountDownLatch.ReentrantLock和ThreadLocal.还涉及 ...
- Java高并发编程学习(三)java.util.concurrent包
简介 我们已经学习了形成Java并发程序设计基础的底层构建块,但对于实际编程来说,应该尽可能远离底层结构.使用由并发处理的专业人士实现的较高层次的结构要方便得多.要安全得多.例如,对于许多线程问题,可 ...
- 29W 字总结阿里 Java 高并发编程:案例 + 源码 + 面试 + 系统架构设计
下半年的跳槽季已经开始,好多同学已经拿到了不错的 Offer,同时还有一些同学对于 Java 高并发编程还缺少一些深入的理解,不过不用慌,今天老师分享的这份 27W 字的阿里巴巴 Java 高并发编程 ...
- @冰河老师的巨作,人手一册的Java高并发编程指南,值得了解一下
还真不好意思,这次 Java Thread Pool 惊爆了! 高并发是每一个后端开发工程师都头疼的问题,也是工程师能力的分水岭.要想基于JDK核心技术,玩转高并发编程,必须要好好修炼内功才行. 文章 ...
- Java高并发编程:活跃性危险
Java高并发程序中,不得不出现资源竞争以及一些其他严重的问题,比如死锁.线程饥饿.响应性问题和活锁问题.在安全性与活跃性之间通常存在依赖,我们使用加锁机制来确保线程安全,但是如果过度地使用加锁,则可 ...
- Java高并发编程详解系列-7种单例模式
引言 在之前的文章中从技术以及源代码的层面上分析了关于Java高并发的解决方式.这篇博客主要介绍关于单例设计模式.关于单例设计模式大家应该不会陌生,作为GoF23中设计模式中最为基础的设计模式,实现起 ...
- Java高并发编程(二):Java并发机制的底层实现机制
Java代码在编译后会变成Java字节码,字节码在之后被类加载机制加载到JVM中,JVM执行字节码,最终需要转换为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. ...
- Java高并发编程详解系列-Future设计模式
导语 假设,在一个使用场景中有一个任务需要执行比较长的时间,通常需要等待任务执行结束之后或者是中途出错之后才能返回结果.在这个期间调用者只能等待,对于这个结果Future设计模式提供了一种凭据式的 ...
- java高并发编程(二)
马士兵java并发编程的代码,照抄过来,做个记录. 一.分析下面面试题 /*** 曾经的面试题:(淘宝?)* 实现一个容器,提供两个方法,add,size* 写两个线程,线程1添加10个元素到容器中, ...
最新文章
- 2022-2028年中国打印耗材市场现状调研与进展趋势分析报告
- 请注意更新TensorFlow 2.0的旧代码
- 广东时代互联---网络管理面试
- SpringCloud_RibbonHystrixFeign
- WEB中加载ApplicationContext的两种方式
- 全球及中国甲基丙烯酸烷基酯行业深度研究与未来投资潜力分析报告2022版
- C++使用Windows API CreateMutex函数多线程编程
- linux php不支持crypt,(PHP)如何在CRYPT_BLOWFISH中使用crypt()?
- 深度学习(二十二)Dropout浅层理解与实现
- SpaceX 火箭发射成功,一文了解所用的软件技术栈!
- X64-CL iPro 采集卡OC-64EO-IPRO0简介
- 零基础适合学python吗-零基础适合学Python吗?小白能否学会Python?
- java bit mask_位掩码(Bit Mask)的应用
- JRE、JDK下载安装教程
- MA1 轻轻松松学统计分析(上)
- opencv 绿色通道提取
- 【笔记】程序性能优化28个策略原则
- 计算机开机出现alert,开机提示alert! cover was previously removed(主机盖被移动)
- 苹果手机隐私分析数据是什么_苹果公司以用户为中心的隐私保护方法能教给我们什么?
- 如何使用Python生成数据分析报告
热门文章
- 沉默是金不如开口为银
- 哎!马上要涉水了,装修的水!
- [Swift]LeetCode513. 找树左下角的值 | Find Bottom Left Tree Value
- 洛谷 P4175: bzoj 1146: [CTSC2008]网络管理
- HDU2665 求区间第K大 主席树
- 精通JavaScript--01面向对象JavaScript
- .net平台的rabbitmq使用封装
- 在Linux下安装配置phpMyAdmin步骤
- chapter 01
- 计算机辅助药物合成投什么期刊,中国药物化学杂志审稿快吗