在java中實現線程的方式:javascript
main方法其實也是一個線程。
在java中,每次程序運行至少啓動2個線程。一個是main線程,一個是垃圾收集線程。java
yield()方法併發
Thread.yield()方法做用是:暫停當前正在執行的線程對象,並執行其餘線程。
yield()應該作的是讓當前運行線程回到可運行狀態,以容許具備相同優先級的其餘線程得到運行機會。所以,使用yield()的目的是讓相同優先級的線程之間能適當的輪轉執行。可是,實際中沒法保證yield()達到讓步目的,由於讓步的線程還有可能被線程調度程序再次選中。異步
結論:yield()從未致使線程轉到等待/睡眠/阻塞狀態。在大多數狀況下,yield()將致使線程從運行狀態轉到可運行狀態,但有可能沒有效果。async
join()方法
保證當前線程中止執行,直到該線程所加入的線程完成爲止,當前線程方可繼續執行。然而,若是它加入的線程沒有存活,則當前線程不須要中止。ide
執行流程:
構造方法中實例化WorkerRunnable和FutureTask對象。
WorkerRunnable將Params參數封裝,並將本身封裝在FutureTask中,一旦FutureTask執行run方法時,會去調用WorkRunnable的call方法並返回Result值。call方法中就執行了AsyncTask的doInBackground方法。並調用postResult方法將結果發送出去。oop
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
return postResult(result);
}
};
private Result postResult(Result result) {
@SuppressWarnings("unchecked")
Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
new AsyncTaskResult<Result>(this, result));
message.sendToTarget();
return result;
}複製代碼
那麼FutureTask是何時執行的?
FutureTask充當了Runnable的做用,交給SerialExecutor的execute方法執行。FutureTask是一個併發類,能夠中途取消的用於異步計算的類。post
SerialExecutor的execute方法首先把FutureTask插入到mTasks任務隊列中,若是沒有活動的任務,則執行下一個。當一個任務執行完成,會繼續調用scheduleNext方法執行下一個,直到全部任務都被執行。性能
THREAD_POOL_EXECUTOR.execute(mActive);纔是真正執行任務的方法。使用的是ThreadPoolExecutor線程池。ui
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
//將FutureTask插入到mTasks任務隊列中
mTasks.offer(new Runnable() {
public void run() {
try {
// 執行FutureTask的run方法,進而執行call方法
r.run();
} finally {
// 串行執行下一個任務
scheduleNext();
}
}
});
//沒有正在活動的任務,執行下一個AsyncTask。
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}複製代碼
注意:
繼承了Thread類,本質仍是線程。可是能夠直接使用Handler的Thread。在run方法中經過Looper.prepare建立消息隊列,並開啓消息循環。使得能夠再次線程中建立Handler。
同時,它還解決了一個Looper與Handler的同步問題。能夠保證根據當前線程的Looper建立Handler時,Looper對象的獲取不爲空。
參考《深刻理解Android 卷I》159頁
/** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}複製代碼
因爲loop開啓了無限循環,所以能夠經過quit或者quitSafely方法終止線程執行。
典型應用場景就是在IntentService中。
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}複製代碼
一個能夠處理異步請求的Service.服務開啓後,工做線程會依次處理每一個Intent,任務執行完畢後會自動關閉。
相對於線程而言,IntentService更適合執行一些高優先級的後臺任務。
@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.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}複製代碼
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) { }複製代碼
變量
規則