yinbaoshiguang 2019-07-01
线程是CPU调度的最小单位。当一个程序第一次启动的时候,Android 会启动一个 Linux 进程和一个主线程。Android 中所有的组件都在主线程中实例化。主线程主要负责处理 UI 相关的事件,所以又被叫做 UI 线程。在 Android 中主线程是不能够做耗时操作的,子线程是不能够更新UI的。
与进程的区别:
优点:实现简单,只要继承 Thread 类,并重写 run 方法就可以实现多线程。
缺点:
具体使用:
// 步骤1:创建线程类 (继承自Thread类)
class MyThread extends Thread{
@Override
public void run(){
// 步骤2:从写run方法
}
}
// 步骤3:创建线程对象,即 实例化线程类
MyThread mt=new MyThread(“线程名称”);
// 步骤4:通过 线程对象 控制线程的状态,如 运行、睡眠、挂起 / 停止
mt.start();可复用,代码量大
使用匿名类:
new Thread("线程名称") {
@Override
public void run() {
// doSomeThing
}.start();不可复用,简介
注意:Thread 调用 run() 方法,就是一个普通的方法,失去线程的特性;start() 方法才会启动一个线程。
优点:
Java中真正能创建新线程的只有Thread类对象。通过实现Runnable的方式,最终还是通过Thread类对象来创建线程。所以对于实现了Runnable接口的类,称为线程辅助类;Thread类才是真正的线程类。
具体使用:
// 步骤1:创建线程辅助类,实现Runnable接口
class MyRunnable implements Runnable{
@Override
// 步骤2:复写run(),定义线程行为
public void run(){
}
}
// 步骤3:创建线程辅助对象,即 实例化 线程辅助类
MyRunnable mr=new MyRunnable();
// 步骤4:创建线程对象,即 实例化线程类;线程类 = Thread类;创建时通过Thread类的构造函数传入线程辅助类对象
Thread td=new Thread(mr);
// 步骤5:通过 线程对象 控制线程的状态,如 运行、睡眠、挂起 / 停止
td.start();使用匿名类:
Runnable mt = new Runnable() {
@Override
public void run() {
}
};
Thread mt1 = new Thread(mt, "窗口1");
mt1.start();作用:
实现工作线程 & 主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作。从而保证线程安全。
优点:
缺点:
虽然 AsyncTask 的任务执行是通过线程池,线程池的核心线程,非核心线程规格大于1,但是后台运行的线程也只有一个,这是因为 AsyncTask 的任务管理线程池是 串行的 即,执行完一个任务才会执行下一个任务。
类定义:
public abstract class AsyncTask<Params, Progress, Result> {
...
}
// 类中参数为3种泛型类型
// 整体作用:控制AsyncTask子类执行线程任务时各个阶段的返回类型
// 具体说明:
// a. Params:开始异步任务执行时传入的参数类型,对应excute()中传递的参数
// b. Progress:异步任务执行过程中,返回下载进度值的类型
// c. Result:异步任务执行完成后,返回的结果类型,与doInBackground()的返回值类型保持一致
// 注:
// a. 使用时并不是所有类型都被使用
// b. 若无被使用,可用java.lang.Void类型代替
// c. 若有不同业务,需额外再写1个AsyncTask的子类
}AsyncTask 核心 & 常用的方法如下:
使用步骤:
注意:
if (myAsyncTask != null && myAsyncTask.getStatus() == Status.RUNNING) {
//cancel方法只是将对应的AsyncTask标记为cancelt状态,并不是真正的取消线程的执行.
myAsyncTask.cancel(true);
}// AsyncTask 自带的线程池
task1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
// MY_THREAD_POOL_EXECUTOR 为自定义的线程池
task1.executeOnExecutor(MY_THREAD_POOL_EXECUTOR);
task2.executeOnExecutor(MY_THREAD_POOL_EXECUTOR);
// 替换掉默认的 AsyncTask.SERIAL_EXECUTOR
MyAsyncTask.setDefaultExecutor(MY_THREAD_POOL_EXECUTOR);
new MyAsyncTask(mActivity, "Task#a ").execute("abc");
new MyAsyncTask(mActivity, "Task#b ").execute("abc");demo连接:处理了AsyncTask串行、并行问题,自定义线程池,以及AsyncTask内存泄漏的问题
原理:

参考原文:Android 多线程:AsyncTask的原理 及其源码分析
Carson_Ho的原文地址:Android多线程:线程池ThreadPool 全面解析