編輯:關於Android編程
callable和running類似,是一個接口:
public interface Runnable {
public abstract void run();
}
Callable是從Java 1.5開始提供的,位於java.util.concurrent包下:
public interface Callable {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
可以看到,兩者最大的區別就是Callable任務執行完畢之後可以得到任務執行結果。
Future是一個接口:
public interface Future {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
Future提供了三種功能:
1)判斷任務是否完成;
2)能夠中斷任務;
3)能夠獲取任務執行結果。
因為Future只是一個接口,所以是無法直接用來創建對象使用的,因此就有了下面的FutureTask。
FutureTask類實現了RunnableFuture接口,RunnableFuture接口的實現如下:
public interface RunnableFuture extends Runnable, Future {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
可以看出RunnableFuture繼承了Runnable接口和Future接口,所以FutureTask既可以作為Runnable被線程執行,又可以作為Future得到Callable的返回值。
FutureTask提供了2個構造器:
public FutureTask(Callable callable) {
}
public FutureTask(Runnable runnable, V result) {
}
FutureTask實際上是一個任務的操作類,它並不啟動新線程,只是在自己所在線程上操作,任務的具體實現是構造FutureTask時提供的,實現自Callable接口的對象,FutureTask不知道具體的任務是什麼,它只知道如何調度任務,如:
如何啟動任務:在FutureTask的run()方法中(實現自Runnable.run()),調用Callable.call()方法來啟動任務,Callable.call()方法中是任務的具體實現;
如何取消任務:在cancel()裡,中斷執行任務的線程,記錄任務結束狀態,並調用done()方法來執行用戶實現的操作;
如何返回任務的運行結果:如果任務還在執行,則阻塞線程(使用LockSupport.park()),直到任務結束才返回結果,用戶可以通過get()方法來獲取結果,同樣當任務運行結束時,會調用done()來執行用戶實現的操作。
使用FutureTask的好處是,更輕松的對任務進行管理,而不是像Runnable那樣扔進線程後就啥也不能做了。
Executor是任務執行者,它不關心是什麼任務,只關心如何執行任務。Executor是個Interface,具體如何執行任務要看怎麼實現這個接口。
java.util.concurrent.Executor中被注釋的代碼中提供了一個Executor實現的例子:
class SerialExecutor implements Executor {
final Queue tasks = new ArrayDeque();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
@Override
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}
這個實現的意思是,嚴格按照用戶提交的順序來串行的執行任務(當前任務運行結束,再運行下一個)。Android的AsyncTask就使用了這個例子。當然用戶也可以提供自己的Executor來改變AsyncTask的運行方式。
AsyncTask提供了一種簡便的異步處理機制,但是它又同時引入了一些令人厭惡的麻煩。一旦對AsyncTask使用不當,很可能對程序的性能帶來負面影響,同時還可能導致內存洩露。
1、假設按照順序啟動20個AsyncTask,一旦其中的某個AsyncTask執行時間過長,隊列中的其他剩余AsyncTask都處於阻塞狀態,必須等到該任務執行完畢之後才能夠有機會執行下一個任務。
為了解決上面提到的線性隊列等待的問題,我們可以使用AsyncTask.executeOnExecutor()強制指定AsyncTask使用線程池並發調度任務。
2、如何才能夠真正的取消一個AsyncTask的執行呢?AsyncTaks有提供cancel()的方法,但是這個方法實際上做了什麼事情呢?線程本身並不具備中止正在執行的代碼的能力,為了能夠讓一個線程更早的被銷毀,我們需要在doInBackground()的代碼中不斷的添加程序是否被中止的判斷邏輯,如下:
<code class="hljs java">@Override protected ArrayList<povideo> doInBackground(Void... params) { if (isCancelled()) return null; for (int i = 0; i<mvideolistadapter.getcount();i++) ...="" code="" if="" override="" protected="" return="" void=""></mvideolistadapter.getcount();i++)></povideo></code>
一旦任務被成功中止,AsyncTask就不會繼續調用onPostExecute(),而是通過調用onCancelled()的回調方法反饋任務執行取消的結果。我們可以根據任務回調到哪個方法(是onPostExecute還是onCancelled)來決定是對UI進行正常的更新還是把對應的任務所占用的內存進行銷毀等。
3、使用AsyncTask很容易導致內存洩漏,一旦把AsyncTask寫成Activity的內部類的形式(非靜態內部類會默認持有外部類的引用)就很容易因為AsyncTask生命周期的不確定而導致Activity發生洩漏。
(一).前言:今天我們的項目繼續更新,今天我們主要講解消息總線EventBus的基本使用方法,後面一篇我們會從源碼的角度稍微分析一下實現過程。Fa
轉載請注明出處 http://blog.csdn.net/typename/ powered by miechal zhao : miechalzhao@gmail.
好久沒有寫文章了,本來想寫的東西,時間一長,就感覺不想寫了,沒什麼用,到用時,又不知道去哪找了或怎麼解決。 有一句話說的好啊,好記性不如爛筆頭。 我要做到善於總結,及時整
進度條可以方便的告訴用戶現在執行任務的進度,特別是一個執行程序比較長的時候,沒有進度條,用戶不知道程序在執行,會以為程序假死強制關閉。 進度條分為:1