Android 多线程

2021-05-24  本文已影响0人  mfdalf

目录

image.png
多线程系列文章
AsyncTask使用和源码分析:https://blog.csdn.net/fdsafwagdagadg6576/article/details/116746753
线程同步-锁:https://www.jianshu.com/p/78d36f6c0ab7
linux c/c++多线程看了肯定懂:https://www.jianshu.com/p/00a97bac4913

正文

一 多线程使用

image
1.1 基础使用Thread 和 Runnable介绍 image
Thread 使用: thread.start 执行thread class的run函数.
Runnable使用: Thread td=new Thread(Runnable mt) ; 执行runnable的run函数
Runnable特性: 由于java不能多继承,所以只能实现runnable接口实现多继承.
Thread,Runnable 使用方法实例: https://blog.csdn.net/weixin_39795146/article/details/81383993
notes: 直接调用thread.run函数不是多线程,只是主线程调用普通函数.thread.start 才是新启动线程.

1.2 复合使用 handlethread和IntentService

HandlerThread继承于Thread,所以它本质就是个Thread。与handler的区别是handler在主线程实现lopper, handlerthread在子线程实现Looper.
HandlerThread使用步骤:1 在子线程创建looper 2 主线程handler加载子线程looper 3 发送&接收:主线程handler sendmessage-->子线程looper-->主线程handler handlemessage
IntentService本质是service. 将HandlerThread使用封装成service就是intentService. 即IntentService=handlerThread使用+onStart,onCommand等service class框架函数.

2 异步通信(并发)callable->futureTask->asynctask

2.1 基础使用Callable接口

callable运行函数体是call,call()函数有返回值.个人认为Callable完全可以代替Runnable.
线程因为有了返回值,为实现异步的提供了基础.

2.2 基础使用 FutureTask-callable或者runnable的包装类

2016-11-30 09-22-12_XMind - D__600.self_05.code_04.java_21.JDK1.6_src_study_21.JDK1.6_src_study_docu
1 ) 使用步骤:

FutureTask使用完整示例 https://blog.csdn.net/lfdfhl/article/details/40739103
notes:FutureTask.get 和pthread_join 作用类似,都是异步阻塞,多了获取执行结果.

futuretask 作用:对callable,runnable做简单包装,成为一个task提供上层一些接口调用.
详细参考: https://my.oschina.net/youranhongcha/blog/1561107 这个bog图和小结很好

小结:
|callalbe|多线程执行体,有返回值|
|futuretask|传入线程或者线程池的都是futuretask. 对callable做了封装。提供返回值接口,get 是block等待子线程结束. done提供子线程完成之后的业务操作|
|asynctask|封装futuretask,使用更方便.
onPreExecute,doInBackground,onProgressUpdate,onPostExecute 提供给用户.还可以配置线程池size.|

2 ) 常用api (api实现参见附录源码链接)

| isDone() | 表示任务是否开始(详见源码) |
| get()/get(timeout) | 真正的判断是否完成的方法。
它会产生永久阻塞或者阻塞timeout,等到任务执行完毕才返回。 |
| Done | 当任务结束时,该回调函数会被触发。因此,只需重载该函数,即可实现在线程刚结束时就做一些事情。 |

3 ) CompletableFuture

看的不多,感觉就是多个futuretask一个接一个执行。变成一组线程完成一件事。

2.3 Asynctas :参见 https://blog.csdn.net/fdsafwagdagadg6576/article/details/116746753

**3 线程池(ThreadPool) **

ThreadPoolExecutor继承自ExecutorService.
Android线程池使用ThreadPoolExecutor,只能传入runnable or callable类以及其子类,不能传入thread类.
C++线程池使用方法是,向它里面直接传入对象,然后执行对象的run函数.eg: g_threadpool

使用实例:

Executor threadPool = new ThreadPoolExecutor(...);
threadPool.execute(ThreadTask);
public class ThreadTask implements Runnable{    
    public void run() {
          ... // 线程执行任务
    }

小结对比

image

二 线程同步-锁(排它lock和唤醒)

请参考:https://blog.csdn.net/fdsafwagdagadg6576/article/details/116807675

三 线程通信

实际有3种方式,1是condition条件(最常用)。2 是生产者&消费者线程轮询访问同一个全局变量。3 是epoll监听文件(比如:handler机制)

JDK AQS
wait await
notify singal
notifyAll singalAll

参考引用:

Android:关于多线程的总结知识都在这里了 https://www.jianshu.com/p/5225824ec967
Android多线程:线程池ThreadPool 全面解析 https://www.jianshu.com/p/0e4a5e70bf0e
FutureTask源码阅读:https://blog.csdn.net/xingzhong128/article/details/80553789

讨论:异步非阻塞怎么实现呢

1 常见的异步阻塞用法

while { select(...)...} //loop+select
Futuretask.get 和pthread_join //阻塞等待结果

网上把这些例子归为异步阻塞,但是本质还是阻塞串行,并没有多线程独立的异步工作

2 异步非阻塞:

软件UI界面.点击那个控件就相应处理了.后台下载,等于一个线程在下载,确实不影响UI线程影响其他消息,鼠标操作。--windows 和android的input system没搞懂
观察者模式+线程池:订阅之后,来个事件交给线程池,不影响继续处理下一个来的event.实现异步非阻塞.比如:AsyncEventbus.
参考:https://blog.csdn.net/aha_jasper/article/details/108608718---有一个map绑定消息和observable回调函数,将需要执行的函数和对象放入线程池
信号回调:多进程的异步非阻塞

上一篇下一篇

猜你喜欢

热点阅读