进程优先级
Foreground Process:前台进程,用户可见,被遮挡,虽然可见,但是不属于前台进程;
Background Process:后台进程,用户不可见,进程包含service,重要性高,也存在空进程,不做任何事情。
先立个大纲,明天写吧(2017年1月11日20:19:49)
线程调度
- 线程在程序中是独立的,并发的执行流,与进程相比,进程中的线程隔离程度小,共享内存,文件句柄,和进程应有的状态。
- 进程执行过程中拥有独立内存单元,多线程共享内存,提高程序运行效率。
- 线程共享进程代码段,进程共有数据,可很容易实现线程间相互通信。
- 进程间不能共享内存,线程共享相对容易的多。
- 创建线程实现多任务并发比多线程来说效率高。
thread runnable
创建线程和启动线程:
继承自Thread,重写run方法;
实现Runnable接口,并重写Runnable的run方法;
1 public class MyThread extends Thread {
2
3 @Override
4 public void run() {
5 super.run();
6 Log.i("MyThreadName = ",this.getName());
7 }
8 }
public class MyRunnable implements Runnable {
@Override
public void run() {
Log.i("MyRunnable_ThreadName=",Thread.currentThread().getName());
}
}
两种实现方式的区别:
采用Runnable实现,
- 线程类只是实现Runnable接口还可以继承自其他类;
- 可以实现共享同一target对象,使用相同线程处理同一资源的情况。
采用Thread实现:
不能继承其他父类;
无需使用Thread,currentThread()来获取当前线程,使用this就行。
线程生命周期:
new 新建状态,java虚拟机分配内存并初始化成员变量的值。
start 就绪状态,虚拟机创建栈和程序计数器,线程没有开始运行,只是可以运行。
运行状态:就绪状态线程获得CPU,执行run方法的线程执行体。
阻塞状态:
- 线程调用sleep方法主动放弃所占用的处理器资源;
- 线程调用阻塞IO方法,在该方法返回之前,线程阻塞;
- 线程获取同步监视器,同步监视器被其他线程持有;
- 线程等待通知(notify);
- 线程调用suspend将线程挂起,容易死锁,不建议使用。
重新进入就绪状态:
- 调用sleep的线程到了指定时间;
- 线程阻塞io已经返回;
- 线程成功获取同步监视器;
- 线程正在等待通知,其他线程发出通知;
- 处于关闭的线程调用resume恢复。
线程死亡:
- run方法执行完成,线程正常结束;
- 线程抛出Exception或者Error;
- 直接调用线程stop方法结束该线程(容易死锁,不建议使用)。
控制线程:
join()方法:调用线程阻塞,知道被join方法加入的join线程完成为止;
- join():等待被join线程执行完成;
- join(long millis):等待被join时间最长为millis毫秒,如果超出millis毫秒时间则不继续等待;
- join(long millis, int nanos):等待被join的线程时间为millis毫秒+nanos微秒;
AsyncTask
轻量级异步任务类,内部封装了Thread和Handler,但是不适合特别耗时的后台任务,特别耗时间的建议使用线程池。
三个泛型参数
1. Params
在执行AsyncTask时需要传入的参数,可用于在后台任务中使用。
2. Progress
后台任何执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
3. Result
当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值类型。
几个核心方法:
1. onPreExecute()(UI线程)
这个方法会在后台任务开始执行之间调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框。
2. doInBackground(Params...)(异步子线程)
这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任务。任务一旦完成就可以通过return语句来将任务的执行结果进行返回,如果AsyncTask的第三个泛型参数指定的是Void,就可以不返回任务执行结果。注意,在这个方法中是不可以进行UI操作的,如果需要更新UI元素,比如说反馈当前任务的执行进度,可以调用publishProgress(Progress...)方法来完成。
3. onProgressUpdate(Progress...)(UI线程)
当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对UI进行操作,利用参数中的数值就可以对界面元素进行相应的更新。
4. onPostExecute(Result)(UI线程)
当后台任务执行完毕并通过return语句进行返回时,这个方法就很快会被调用。返回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些UI操作,比如关闭掉进度条对话框。
注意点:
- AsyncTask必须主线程调用;
- AsyncTask必须主线程创建对象;
- execute必须主线程调用;
- android 1.6之前 串行执行任务,1.6改成线程池并行执行,android3.0后采用一个线程串行执行,但是可以调用executeOnExcutor方法来并行执行任务。
AnsyTask源码分析:
首先ansyTask是一个抽象类,需要子类去实现:
1 public abstract class AsyncTask<Params, Progress, Result>{
2
3 }
因为要调用AnsyTask需要初始化对象,所以我们先看下它的构造方法:
1 /**
2 * Creates a new asynchronous task. This constructor must be invoked on the UI thread.
3 */
4 public AsyncTask() {
5 mWorker = new WorkerRunnable<Params, Result>() {
6 public Result call() throws Exception {
7 mTaskInvoked.set(true);
8
9 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
10 //noinspection unchecked
11 Result result = doInBackground(mParams);
12 Binder.flushPendingCommands();
13 return postResult(result);
14 }
15 };
16
17 mFuture = new FutureTask<Result>(mWorker) {
18 @Override
19 protected void done() {
20 try {
21 postResultIfNotInvoked(get());
22 } catch (InterruptedException e) {
23 android.util.Log.w(LOG_TAG, e);
24 } catch (ExecutionException e) {
25 throw new RuntimeException("An error occurred while executing doInBackground()",
26 e.getCause());
27 } catch (CancellationException e) {
28 postResultIfNotInvoked(null);
29 }
30 }
31 };
32 }
必须在UI线程进行初始化操作,初始化mWorker,mFuture两个对象,初始化mWorker首先 mTaskInvoked.set(true);表示当前任务已经被调用过了,mWorker调用AsyncTask的doinBackground执行耗时操作,返回值传递给postResult方法。
看下postResult方法:
1 private Result postResult(Result result) {
2 @SuppressWarnings("unchecked")
3 Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
4 new AsyncTaskResult<Result>(this, result));
5 message.sendToTarget();
6 return result;
7 }
看下hander:
1 private static Handler getHandler() {
2 synchronized (AsyncTask.class) {
3 if (sHandler == null) {
4 sHandler = new InternalHandler();
5 }
6 return sHandler;
7 }
8 }
1 private static class InternalHandler extends Handler {
2 public InternalHandler() {
3 super(Looper.getMainLooper());
4 }
5
6 @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
7 @Override
8 public void handleMessage(Message msg) {
9 AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
10 switch (msg.what) {
11 case MESSAGE_POST_RESULT:
12 // There is only one result
13 result.mTask.finish(result.mData[0]);
14 break;
15 case MESSAGE_POST_PROGRESS:
16 result.mTask.onProgressUpdate(result.mData);
17 break;
18 }
19 }
20 }
很明显调用第13行进而调用:
1 private void finish(Result result) {
2 if (isCancelled()) {
3 onCancelled(result);
4 } else {
5 onPostExecute(result);
6 }
7 mStatus = Status.FINISHED;
8 }
如果取消调用onCancelled(result)否则调用onPostExcute(result)进行UI线程的操作。
然后我们代码中还会调用execute()方法:
1 @MainThread
2 public final AsyncTask<Params, Progress, Result> execute(Params... params) {
3 return executeOnExecutor(sDefaultExecutor, params);
4 }
1 @MainThread
2 public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
3 Params... params) {
4 if (mStatus != Status.PENDING) {
5 switch (mStatus) {
6 case RUNNING:
7 throw new IllegalStateException("Cannot execute task:"
8 + " the task is already running.");
9 case FINISHED:
10 throw new IllegalStateException("Cannot execute task:"
11 + " the task has already been executed "
12 + "(a task can be executed only once)");
13 }
14 }
15
16 mStatus = Status.RUNNING;
17
18 onPreExecute();
19
20 mWorker.mParams = params;
21 exec.execute(mFuture);
22
23 return this;
24 }
sDefaultExecutor:
1 public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
2 private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
3 private static class SerialExecutor implements Executor {
4 final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
5 Runnable mActive;
6
7 public synchronized void execute(final Runnable r) {
8 mTasks.offer(new Runnable() {
9 public void run() {
10 try {
11 r.run();
12 } finally {
13 scheduleNext();
14 }
15 }
16 });
17 if (mActive == null) {
18 scheduleNext();
19 }
20 }
21
22 protected synchronized void scheduleNext() {
23 if ((mActive = mTasks.poll()) != null) {
24 THREAD_POOL_EXECUTOR.execute(mActive);
25 }
26 }
27 }
首先给ArrayDeque<Runnable>队列尾部插入runnable对象,run里面如果出现异常调用Executor的excute方法(THREAD_POOL_EXECUTOR.execute(mActive););
HandlerThread
如下面代码所示:HandlerThread是继承自Thread,并且可使用Handler的Thread,通过在线程里面实现Looper.prepare()和Looper.loop()实现创建队列,和轮训队列的操作。
HandlerThread源码:
1 /**
2 * Handy class for starting a new thread that has a looper. The looper can then be
3 * used to create handler classes. Note that start() must still be called.
4 *启动一个携带有looper的线程,用来创建handler类。启动这个线程通过start()来实现。
5 */
6 public class HandlerThread extends Thread {
7 //线程的优先级
8 int mPriority;
9 //当前线程id
10 int mTid = -1;
11 //当前线程持有的Looper对象
12 Looper mLooper;
13
14 //有参构造方法,优先级为默认优先级,
15 public HandlerThread(String name) {
16 super(name); 17 mPriority = Process.THREAD_PRIORITY_DEFAULT; 18 } 19 20 /** 21 * Constructs a HandlerThread. 22 *有参数构造方法,可以手动传递线程优先级。 23 * @param name 24 * @param priority The priority to run the thread at. The value supplied must be from 25 * {@link android.os.Process} and not from java.lang.Thread. 26 */ 27 public HandlerThread(String name, int priority) { 28 super(name); 29 mPriority = priority; 30 } 31 32 /** 33 * Call back method that can be explicitly overridden if needed to execute some 34 * setup before Looper loops. 35 *回调方法可以实现在Looper.loop()之前的操作 36 */ 37 protected void onLooperPrepared() { 38 } 39 40 /** 41 *关键部分 42 * 43 */ 44 45 @Override 46 public void run() { 47 //获得当前线程的id 48 mTid = Process.myTid(); 49 //准备循环条件 50 Looper.prepare(); 51 synchronized (this) {
//获取到Looper对象 52 mLooper = Looper.myLooper();
第50行调用如下代码,进行Looper的初始化操作
1 /** Initialize the current thread as a looper.
2 * This gives you a chance to create handlers that then reference
3 * this looper, before actually starting the loop. Be sure to call
4 * {@link #loop()} after calling this method, and end it by calling
5 * {@link #quit()}.
*进行初始化操作,通过Looper.loop()进行循环处理,通过调用quit结束操作。
6 */
7 public static void prepare() {
8 prepare(true);
9 }
10
11 private static void prepare(boolean quitAllowed) {
12 if (sThreadLocal.get() != null) {
13 throw new RuntimeException("Only one Looper may be created per thread"); 14 } 15 sThreadLocal.set(new Looper(quitAllowed)); 16 }
消息队列里面的quit方法:
1 void quit(boolean safe) {
2 if (!mQuitAllowed) {
3 throw new IllegalStateException("Main thread not allowed to quit.");
4 }
5
6 synchronized (this) {
7 if (mQuitting) { 8 return; 9 } 10 mQuitting = true; 11 12 if (safe) { 13 removeAllFutureMessagesLocked(); 14 } else { 15 removeAllMessagesLocked(); 16 } 17 18 // We can assume mPtr != 0 because mQuitting was previously false. 19 nativeWake(mPtr); 20 } 21 }
ThreadPoolExecutor
优点:
- 重用线程池中的线程,避免因为线程的原因和销毁所带来的性能消耗;
- 能有效控制线程池的并发数,避免资源抢占导致的阻塞现象。
看下ThreadPoolExecutor的构造方法:
1 public ThreadPoolExecutor(int corePoolSize,
2 int maximumPoolSize,
3 long keepAliveTime,
4 TimeUnit unit,
5 BlockingQueue<Runnable> workQueue,
6 ThreadFactory threadFactory,
7 RejectedExecutionHandler handler)
corePoolSize:核心线程池数,默认情况一直存活,即使是闲置状态。
maximumPoolSize:最大线程数,如果超出这个值,就会阻塞。
keepAliveTime:超时时长。超过非核心线程就会被回收。
unit:keepAliveTime的时间单位,(TimeUnit.SECOND,TimeUnit.MILLISECONDS,TimeUnit.MINUTES)。
workQueue:任务队列,execute方法提交的Runnable对象存在这个参数里面。
threadFactory:线程工程,为线程提供新线程的功能。
先贴个以前写线程池这块的工具类:
1 import java.util.concurrent.ExecutorService;
2 import java.util.concurrent.Executors;
3 import java.util.concurrent.Future;
4 import java.util.concurrent.ScheduledExecutorService;
5 import java.util.concurrent.TimeUnit;
6
7 /**
8 * @类名: ThreadUtils
9 * @描述: TODO(线程池工具类)
10 * @作者: soyoungboy
11 */
12 public class ThreadUtils {
13 /**
14 * 单线程
15 */
16 static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
17 private static volatile ThreadUtils instance = null;
18 /**
19 * 初始化的线程数,有待历史的验证,暂时弄4个
20 */
21 public ExecutorService threadPool = Executors.newFixedThreadPool(4);
22 /**
23 * 执行延迟任务,类似Timer的效果
24 */
25 public ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(2);
26
27 // private constructor suppresses
28 private ThreadUtils() {
29
30 }
31
32 public static ThreadUtils getInstance() {
33 // if already inited, no need to get lock everytime
34 if (instance == null) {
35 synchronized (ThreadUtils.class) {
36 if (instance == null) {
37 instance = new ThreadUtils();
38 }
39 }
40 }
41
42 return instance;
43 }
44
45 /**
46 * 立即执行任务
47 *
48 * @param task ThreadUtils.getInstance().excute(run);
49 */
50 public void excute(Runnable task) {
51 threadPool.execute(task);
52 }
53
54 /**
55 * 单线程持操作,主要用于数据库的读写异步操作
56 *
57 * @param task ThreadUtils.getInstance().excuteSingleThread(run);
58 * @return
59 */
60 public Future excuteSingleThread(Runnable task) {
61 return singleThreadPool.submit(task);
62 }
63
64 ;
65
66 /**
67 * 延后执行任务
68 *
69 * @param task
70 * @param delay ThreadUtils.getInstance().schedule(run,1000);
71 */
72 public void schedule(Runnable task, long delay) {
73 scheduleThreadPool.schedule(task, delay, TimeUnit.MILLISECONDS);
74 }
75
76 public Future execuse(final Task task) {
77 task.onstart();
78 Future future = excuteSingleThread(new Runnable() {
79 @Override
80 public void run() {
81 try {
82 task.doInBackground();
83 } catch (Exception e) {
84 task.transfer(null, Task.TRANSFER_DOERROR);
85 return;
86 }
87 task.transfer(null, Task.TRANSFER_DOUI);
88 }
89 });
90 return future;
91 }
92
93
94 /**
95 * @param 设定文件
96 * @return void 返回类型
97 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownThreadPool()]
98 * @Title: shutdownThreadPool
99 * @Description: TODO()
100 */
101 public void shutdownThreadPool() {
102 threadPool.shutdownNow();
103 }
104
105 /**
106 * @param 设定文件
107 * @return void 返回类型
108 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownScheduleThreadPool()]
109 * @Title: shutdownThreadPool
110 * @Description: TODO()
111 */
112 public void shutdownScheduleThreadPool() {
113 scheduleThreadPool.shutdownNow();
114
115 }
116
117 /**
118 * @param 设定文件
119 * @return void 返回类型
120 * @throws 在onDestory ()中执行[ThreadUtils.getInstance().shutdownSingleThreadPool()]
121 * @Title: shutdownSingleThreadPool
122 * @Description: TODO(单线程池销毁操作)
123 */
124 public void shutdownSingleThreadPool() {
125 singleThreadPool.shutdownNow();
126 }
127 }
ThreadPoolExecutor是线程的真正实现;
线程池的分类:
1,FixedThreadPool
FixedThreadPool 线程数量固定的线程池,例如上面代码中如下字段:
1 public ExecutorService threadPool = Executors.newFixedThreadPool(4)
线程数量固定为4,线程空闲不回回收,除非线程关闭。
2,CacheThreadPool
线程数量不固定的线程池,最大线程数为Int最大值。
3,scheduledThreadPool
核心线程数固定,非核心线程不固定,闲置时非核心线程会立刻被回收,执行定时任务和具有固定周期的重复任务。
/**
* 执行延迟任务,类似Timer的效果
*/
public ScheduledExecutorService scheduleThreadPool = Executors.newScheduledThreadPool(2);
使用如下:
/**
* 延后执行任务
*
* @param task
* @param delay ThreadUtils.getInstance().schedule(run,1000);
*/
public void schedule(Runnable task, long delay) {
scheduleThreadPool.schedule(task, delay, TimeUnit.MILLISECONDS);
}
4,SingleThreadExcutor
SingleThreadExcutor单线程池,只有一个核心线程,所有任务再同一线程中按序执行,不回存在线程同步问题。
声明:
/**
* 单线程
*/
static ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
使用:
/**
* 单线程持操作,主要用于数据库的读写异步操作
*
* @param task ThreadUtils.getInstance().excuteSingleThread(run);
* @return
*/
public Future excuteSingleThread(Runnable task) {
return singleThreadPool.submit(task);
}
IntentService:
IntentService是继承自service并异步处理耗时操作,当任务执行完毕,自动停止。可以启动多次,耗时操作在IntentService的onHandIntent中进行,所有请求都在单一线程中,并且每次只执行一个异步任务。
IntentService的优点:
- 不用手动在service中创建线程;
- 操作完成后不用手动关闭service。
首先贴下IntentService的源码,很短:
/**
* IntentService is a base class for {@link Service}s that handle asynchronous
* requests (expressed as {@link Intent}s) on demand. Clients send requests
* through {@link android.content.Context#startService(Intent)} calls; the
* service is started as needed, handles each Intent in turn using a worker
* thread, and stops itself when it runs out of work.
*
* <p>This "work queue processor" pattern is commonly used to offload tasks
* from an application's main thread. The IntentService class exists to
* simplify this pattern and take care of the mechanics. To use it, extend
* IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
* will receive the Intents, launch a worker thread, and stop the service as
* appropriate.
*
* <p>All requests are handled on a single worker thread -- they may take as
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
*
* <div class="special reference">
* <h3>Developer Guides</h3>
* <p>For a detailed discussion about how to create services, read the
* <a href="{@docRoot}guide/topics/fundamentals/services.html">Services</a> developer guide.</p>
* </div>
*
* @see android.os.AsyncTask
*/
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
//调用onHandleIntent
//调用stopSelf自动关闭Service
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService(String name) {
super();
mName = name;
}
/**
* Sets intent redelivery preferences. Usually called from the constructor
* with your preferred semantics.
*
* <p>If enabled is true,
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_REDELIVER_INTENT}, so if this process dies before
* {@link #onHandleIntent(Intent)} returns, the process will be restarted
* and the intent redelivered. If multiple Intents have been sent, only
* the most recent one is guaranteed to be redelivered.
*
* <p>If enabled is false (the default),
* {@link #onStartCommand(Intent, int, int)} will return
* {@link Service#START_NOT_STICKY}, and if the process dies, the Intent
* dies along with it.
*设置当进程被重建时是否需要重新接受意图,true表示需要,并且当有多个意图时,只能保证最近的一个可以收到。
*/
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
//HandlerThread是集成自Thread的子类,与ServiceHandler进行关联
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*这个不重写,主要重写onHandleIntent
*/
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
/**
* Unless you provide binding for your service, you don't need to implement this
* method, because the default implementation returns null.
* @see android.app.Service#onBind
*/
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
/**
* 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 android.app.Service#onStartCommand}
* for details.
*/
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
继承自Service,在异步线程处理任务,通过startService启动,当任务完成会自动停止,不用手动处理,耗时任务会以队列形式在onHandleIntent中依次执行,然后结束。
oncreate()中创建并执行HandlerThread,也就是实现对MessageQqueue队列的循环遍历操作,将消息分发给Handler的handlerMessage方法 。
onStartCommand()调用onStart,发消息并由ServiceHandler的handleMessage来进行处理。
IntentService启动了线程里面带有Looper的线程,具有消息处理的能力,最后通过onHandleIntent()来处理,执行完后通过stopSelf()来停掉自己。
onHandleIntent抽象方法,需要子类实现。
1 onHandleIntent((Intent)msg.obj);
2 stopSelf(msg.arg1);