目录
1,线程Thread
1.1 Thread概念
1.2 Thread 几种状态
1.3 Thread 主要函数
1.4 Thread 的使用
1.5 Thread 安全与Thread 同步
2,多线程的实现方式
2.1 Handler+Thread github上demo地址 https:///labiqi/android-download 2.2 AsyncTask github上demo地址 https:///labiqi/pdfView 2.3 IntentService
2.4 ThreadPoolExecutor
2.5 RxJava
1 线程Thread
1.1 Thread概念
线程,可以看作是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程可并发执行,并且共享进程资源。
1.2 Thread 几种状态
新建状态(New) 实例化之后进入该状态;
就绪状态(Runnable) 线程调用start()之后就绪状态等待cpu执行,注意这时只是表示可以运行并不代表已经运行;若被线程调度程序调度,这个线程便会成为当前运行(Running)的线程;
阻塞状态(Blocked)线程由于各种原因进入阻塞状态:join()、sleep()、wait()、等待触发条件、等待由别的线程占用的锁;比如若一段代码被线程A”上锁“,此时线程B尝试执行这段代码,线程B就会进入Blocked状态
等待(Waiting) 当线程等待另一个线程通知线程调度器一个条件时,它本身就会进入Waiting状态;
计时等待(Time Waiting) 计时等待与等待的区别是,线程只等待一定的时间,若超时则不再等待;
被终止(Terminated)线程的run方法执行完毕或者由于一个未捕获的异常导致run方法意外终止会进入Terminated状态。
public static enum State {
BLOCKED,
NEW,
RUNNABLE,
TERMINATED,
TIMED_WAITING,
WAITING;
private State() {
}
}1.3 Thread 主要函数

1.4 Thread 的使用
1,继承Thread,重写run()方法,使用时直接new并且start()
public class MyThread extends Thread {
@Override
public void run() {
super.run();
//todo something
}
}
public void startThread() {
new MyThread().start();
}2,从上面的方法的源码我们可知,其实Thread运行时是调用了Runnable 接口中的run方法,那么我们可以重新定义一个类实现Runnable 接口中的run方法:但是这种显示创建线程的方法不建议使用。
public class MyRunnable implements Runnable {
@Override
public void run() {
//todo something
}
}
public void startThread() {
new Thread(new MyRunnable()).start();
}
也可以使用匿名内部类实现:
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();3,通过Handler启动线程。
private Handler mHandler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
Log.d("当前线程",Thread.currentThread().getName());
btn1.setText("当前线程为ui线程");
}
};
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(runnable); // handler运行runnable
}
});handler.post®其实这样并不会新起线程,只是执行的runnable里的run()方法,却没有执行start()方法,所以runnable走的还是UI线程。如果像这样,是可以操作ui,但是run还是走在主线程,见打印出来的Log线程名字是main,说明是主线程。


1.5 Thread 安全与Thread 同步
线程安全问题是指多个线程访问同一代码或数据,造成结果和数据的错乱或与期望的结果不同所产生的问题。采用“序列化访问临界资源”的方案,即在同一时刻只能有一个线程访问临界资源(多个线程可能同时访问的数据或资源),也称同步互斥访问。常见的有以下几种方式:
1,synchronized 关键字,保证同时刻只有一个线程进入该方法或者代码块
线程run()方法添加synchronized关键字
public class MyThread extends Thread {
@Override
public void run() {
super.run();
count();
}
}
private synchronized void count() {
//todo something
}同步代码块的形式使用
private void count() {
if(synchronized (this) {
//todo something
}
}2,特殊域变量volatile修饰变量:告诉虚拟机该变量随时可能更新,因此使用时每次都会重新计算,而不是使用寄存器的值。volatile不会提供任何原子操作,它也不能用来修饰final类型的变量。(不能完全保证线程安全)
private volatile int num = 1000;
3,使用重入锁实现线程同步:lock() :获得锁,unlock() : 释放锁。
private void threadRunFunction() {
lock.lock();
//todo something
lock.unlock();
}2,多线程的实现方式
2.1 Handler+Thread
Android主线程包含一个消息队列(MessageQueue),该消息队列里面可以存入一系列的Message或Runnable对象。通过一个Handler你可以往这个消息队列发送Message或者Runnable对象,并且处理这些对象。每次你新创建一个Handle对象,它会绑定于创建它的线程(也就是UI线程)以及该线程的消息队列,从这时起,这个handler就会开始把Message或Runnable对象传递到消息队列中,并在它们出队列的时候执行它们。
优缺点
- Handler用法简单明了,可以将多个异步任务更新UI的代码放在一起,清晰明了;
- 处理单个异步任务代码略显多。
适用范围 - 多个异步任务的更新UI。
具体关于Handler的讲解可以看另外一篇博客以及github上demo地址 https:///labiqi/android-download。
2.2 AsyncTask
AsyncTask是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。AsyncTask通过一个阻塞队列BlockingQuery存储待执行的任务,利用静态线程池THREAD_POOL_EXECUTOR提供一定数量的线程,默认128个。在Android 3.0以前,默认采取的是并行任务执行器,3.0以后改成了默认采用串行任务执行器,通过静态串行任务执行器SERIAL_EXECUTOR控制任务串行执行,循环取出任务交给THREAD_POOL_EXECUTOR中的线程执行,执行完一个,再执行下一个。
构建AsyncTask子类的泛型参数
AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承.继承AsyncTask需要指定如下三个泛型参数:
Params:启动任务时输入的参数类型.
Progress:后台任务执行中返回进度值的类型.
Result:后台任务执行完成后返回结果的类型.
构建AsyncTask子类的回调方法
AsyncTask主要有如下几个方法:
doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成.
onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作.
onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新.
onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法.通过此方法我们可以知晓任务的完成进度.
使用AsyncTask的注意事项
① 必须在UI线程中创建AsyncTask的实例.
② 只能在UI线程中调用AsyncTask的execute方法.
③ AsyncTask被重写的四个方法是系统自动调用的,不应手动调用.
④ 每个AsyncTask只能被执行(execute方法)一次,多次执行将会引发异常.
⑤ AsyncTask的四个方法,只有doInBackground方法是运行在其他线程中,其他三个方法都运行在UI线程中,也就说其他三个方法都可以进行UI的更新操作.
AsyncTask优缺点
处理单个异步任务简单,可以获取到异步任务的进度;
可以通过cancel方法取消还没执行完的AsyncTask;
处理多个异步任务代码显得较多。
适用范围
单个异步任务的处理。
AsyncTask github上demo地址 https:///labiqi/pdfView2.3 IntentService
IntentService是一个基础类,用于处理Intent类型的异步任务请求。当客户端调用android.content.Context#startService(Intent)发送请求时,Service服务被启动,且在其内部构建一个工作线程来处理Intent请求。当工作线程执行结束,Service服务会自动停止。IntentService是一个抽象类,用户必须实现一个子类去继承它,且必须实现IntentService里面的抽象方法onHandleIntent来处理异步任务请求。查看源码可知:
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
//搭建一套Handler的处理机制
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
......
/**
* This method is invoked on the worker thread with a request to process.
* Only one Intent is processed at a time, but the processing happens on a
* worker thread that runs independently from other application logic.
* So, if this code takes a long time, it will hold up other requests to
* the same IntentService, but it will not hold up anything else.
* When all requests have been handled, the IntentService stops itself,
* so you should not call {@link #stopSelf}.
*
* @param intent The value passed to {@link
* android.content.Context#startService(Intent)}.
* This may be null if the service is being restarted after
* its process has gone away; see
* {@link .Service#onStartCommand}
* for details.
*/
@WorkerThread
//抽象方法,必须实现,此方法实现异步任务
protected abstract void onHandleIntent(@Nullable Intent intent);由于IntentService 是继承自Service类,其他使用方式跟Service是一样的
12.4 ThreadPoolExecutor
1.Executors.newFixedThreadPool() 创建一个定长的线程池,每提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化2.Executors.newCachedThreadPool() 创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时, 它可以灵活的添加新的线程,而不会对池的长度作任何限制3.Executors.newScheduledThreadPool() 创建一个定长的线程池,而且支持定时的以及周期性的任务执行,类似于Timer4.Executors.newSingleThreadExecutor() 创建一个单线程化的executor,它只创建唯一的worker线程来执行任务。
2.5 RxJava
RxJava 是一个 基于事件流、实现异步操作的库,是一个强大的第三方开源库,随笔的博客。
















