android 的多线程 实现方法,android 线程的高级使用

作者:机智的张尼玛
楔子苏格拉底曾说过:“学会了多线程,你就学会了压榨CPU,就好像资本家对无产阶级做的那事一样 。”
多线程是开发人员必不可少的技术点,也是初学者不太容易掌握好的一个难点 。要想设计出优秀的程序,那必然需要合理的线程调度 。今天就给大家细说下Android中与多线程相关的知识点,揭开多线程神秘的面纱 。
本篇文章仅介绍多线程的各种实现方式,不过多涉及深入的基础原理探究,达到“所见即所学 , 所学即可用”的效果 。关于各种多线程原理的深入探究 , 有机会放在后面逐一介绍 。
一、多线程是什么?我为什么要用多线程? 1.1 线程和进程的概念
按照操作系统中的描述,线程是CPU调度的最小单元,同时线程是一种有限的系统资源 。而进程一般指一个执行单元,在PC和移动设备上指一个程序或者一个应用 。一个进程可以包含多个线程 。
简单点理解,一个Android APP就是一个进程,一个APP里面有多个线程,我们多线程编程的意义就是实现“一个APP多个线程” 。
有杠精可能会问,那我可不可以一个APP多个进程?又可不可以一个进程只有一个线程?
我告诉你 , 可以 , 都可以 。
单线程的APP只包括Android的UI线程也是能运行的;一个APP多个进程也是可以达到的 , 实现方式涉及到Android的IPC机制 , 这里不细说 。
1.2 为什么要使用多线程?
这里杠精可能会说,那你单线程也能跑,我为啥还要整多线程?
我告诉你,首先这句话从Android开发的角度来讲,近似于一个假命题 。因为谷歌爸爸现在强制规定了不能在UI线程进行耗时操作,必须放到子线程里面去,除非你的程序不涉及耗时操作 。究其原因,是因为在UI线程进行耗时操作的话,给用户的使用体验就是界面“卡顿” 。同时,如果UI线程被阻塞超过一定时间会触发ANR(Application Not Responding)错误 。
从底层的角度来讲,多线程可以使得整个环境能够异步执行,这有助于防止浪费CPU时钟周期从而提高效率 。换言之,多线程能更充分的利用CPU资源,从而提高程序的运行效率 。
二、那我怎么进行多线程编程?2.1 Thread类和Runnable接口要想定义一个线程只需要新建一个类继承自Thread,然后重写父类的run方法即可
class MyThread extends Thread {@Overridepublic void run() {doSomething();}}//在需要的时候启动线程new MyThread().start();优化一下?
我们可以没必要继承整个Thread类,只实现Runnable接口就好了
class MyThread implements Runnable {@Overridepublic void run() {doSomething()}}//启动线程MyThread myThread = new MyThread();new Thread(myThread).start();那我不想专门再写一个线程类怎么办?可以使用匿名类
new Thread(new Runnable() {@Overridepublic void run() {doSomething();}}).start();2.2 线程池
2.2.1 线程池的意义既然我都会用Runnable接口来创建线程了,还要线程池干啥?其实不然,随意创建线程的操作在实际开发中是极为不推荐的 。为啥?因为线程也是一种资源,反复的创建和销毁线程会带来一定性能上的额外开销 。与其相比,线程池主要有以下几个优点:
重用线程池中的线程,避免因为线程的创建和销毁所带来的性能开销能有效控制线程池的最大并发数,避免大量的线程之间因相互抢占系统资源而导致的阻塞现象能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能2.2.2 线程池的结构和原理一个完整的线程池应该有这么几个组成部分
核心线程任务队列非核心线程当我们通过线程池执行异步任务的时候,其实是依次进行了下面的流程