Image img = downloadImg(url);//10秒(或更久)
handleImg(img);
handleOtherTask();//1秒
Image img = downloadImg(url);//10秒(或更久)
handleImg(img);
handleOtherTask();//2秒
new Thread(new Runnable() {
@Override
public void run() {
Image img = downloadImg(url);//10秒(或更久)
handleImg(img);
}
}).start();
handleOtherTask();//1秒
new Thread(new Runnable() {
@Override
public void run() {
Image img = downloadImg(url);//10秒(或更久)
handleImg(img);
}
}).start();
handleOtherTask();//2秒
Client
Service
Data
call
other call
other call return
call return
等待時間
這是一段非常耗時的程式
其他工作
其他工作
Client
Service
Data
call
other call
other call return
立即返回
這是一段非常耗時的程式
其他工作
其他工作
Request
Client
Server
Thread
Future Data
Real Data
Result
Future Object
public class FutureData implements Data{
protected RealData mRealData;
public synchronized void setRealData(RealData realData){
mRealData = realData;
//...
}
public synchronized String getResult() {
//...
return mRealData.result;
}
}
public interface Data {
public String getResult();
}
public class RealData implements Data{
protected String result;
public RealData() {}
public void doTask(){
//..
}
@Override
public String getResult() {
return result;
}
}
public class Client {
private FutureData mFutureData;
public Client(){
mFutureData = new FutureData();
}
public Data request(){
new Thread(){
@Override
public void run() {
RealData realData = new RealData();
realData.doTask();
mFutureData.setRealData(realData);
}
}.start();
return mFutureData;
}
}
Interface Future<V>
All Known Implementing Classes:
ForkJoinTask, FutureTask, RecursiveAction, RecursiveTask, SwingWorker
FutureTask(Callable<V> callable)
FutureTask(Runnable runnable, V result)
FutureTask<Void> futureTask = new FutureTask<>(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("hi");
}, null);
new Thread(futureTask).start();
try {
futureTask.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
return postResult(doInBackground(mParams));
}
};
mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
postResultIfNotInvoked(get());
} catch (InterruptedException e) {
android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occured while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
postResultIfNotInvoked(null);
}
}
};
}
如果多個任務只要一個完成就處理怎麼做?
如果想要全部結果完成才處理怎麼做?
如果想要回來一個就處理一個怎麼做?
ExecutorService threadPool = Executors.newSingleThreadExecutor();
Future<?> future = threadPool.submit(()->System.out.println("hi"));
try {
future.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
public interface ExecutorService extends Executor {
//...
Future<?> submit(Runnable task);
//...
}
ExecutorService threadPool = Executors.newCachedThreadPool();
List<Callable<Integer>> taskList = new ArrayList<>();
taskList.add(()-> {
System.out.println("1");
return 1;
});
taskList.add(()-> {
System.out.println("2");
return 2;
});
taskList.add(()-> {
System.out.println("3");
return 3;
});
try {
List<Future<Integer>> futureList = threadPool.invokeAll(taskList);
} catch (InterruptedException e) {
e.printStackTrace();
}
輸出順序每次都不一樣
ExecutorService threadPool = Executors.newCachedThreadPool();
List<Callable<Integer>> taskList = new ArrayList<>();
taskList.add(()-> 1);
taskList.add(()-> 2);
taskList.add(()-> 3);
try {
Integer value = threadPool.invokeAny(taskList);
System.out.println(value);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
只要一個回來就結束
如果你想要回來一個Task處理一個Task, 可以使用ExecutorCompletionService
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService<String> completionService =
new ExecutorCompletionService<>(executorService);
for(int i = 0; i < 100; i++) {
completionService.submit(getTask(i));
}
//...
String s = completionService.take().get();
你可以用單執行緒, 那就確保送進去的任務按照順序回來, 如果是用多執行緒, 就無法確保回來的順序。
new Thread(new Runnable() {
@Override
public void run() {
//處理Task
runOnUiThread(new Runnable() {
@Override
public void run() {
//更新UI
new Thread(new Runnable() {
@Override
public void run() {
//處理Task
runOnUiThread(new Runnable() {
@Override
public void run() {
}
});
}
}).start();
}
});
}
}).start();
ExecutorService singleThread = Executors.newSingleThreadExecutor();
singleThread.submit(new Runnable() {
@Override
public void run() {
//處理Task
runOnUiThread(new Runnable() {
@Override
public void run() {
//處理Ui
}
});
}
});
singleThread.submit(new Runnable() {
@Override
public void run() {
//處理Task
runOnUiThread(new Runnable() {
@Override
public void run() {
//處理Ui
}
});
}
});
readFileAsync(args[0],
content -> processContentAsync(content,
processedContent -> handleData(content,
c-> out.println(c) ,
ex -> ex.printStackTrace(), service) ,
ex -> ex.printStackTrace(), service),
ex -> ex.printStackTrace(), service);
CompletableFuture
.runAsync(() -> task1)
.thenRunAsync(() -> task2)
.thenRunAsync(() -> task3)
.whenComplete((r, ex) -> System.out.println("done"));
CompletableFuture有以下的概念
public static CompletableFuture<Void> runAsync(Runnable runnable) {
CompletableFuture<Void> future = new CompletableFuture<>();
ForkJoinPool.commonPool().execute(() -> {
try {
runnable.run();
future.complete(null);
} catch (Throwable throwable) {
future.completeExceptionally(throwable);
}
});
return future;
}
//...
CompletableFuture.runAsync(()->handleTask(1)).get();
確保Future可被完成, 或者錯誤處理。
(保證Future原本有的功能存在)
CompletableFuture.runAsync(() -> {
try {
Thread.sleep(1000);
System.out.println("hello");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).whenComplete((result, throwable) -> {
System.out.println("world");
});
加入了Callback來監聽事件
public static void main(String[] args) {
CompletableFuture
.completedFuture(handleTask(1))
.thenApply(result->{
if(result){
System.out.println("task 1 success");
return handleTask(2);
}
System.out.println("task 1 fail");
return result;
})
.thenApply(result -> {
if(result){
System.out.println("task 2 success");
return handleTask(3);
}
System.out.println("task 2 fail");
return false;
})
.whenComplete((result, ex) -> {
if(result) {
System.out.println("task 3 success");
} else {
System.out.println("task 3 fail");
return;
}
System.out.println("all task done");
});
}
public static boolean handleTask(int task){
if(task == 1){return false;}
return true;
}
輸出結果
task 1 fail
task 2 fail
task 3 fail
if(task == 1){return false;}
if(task == 2){return false;}
輸出結果
task 1 success
task 2 fail
task 3 fail
if(task == 3){return false;}
輸出結果
task 1 success
task 2 success
task 3 fail
CompletableFuture<List<Task>> allDoneFuture = sequence(taskList);
//...
private static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) {
CompletableFuture<Void> allDoneFuture =
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
return allDoneFuture.thenApply(v ->
futures.stream().
map(future -> future.join()).
collect(Collectors.<T>toList())
);
}
allOf(...) | 回傳一個future,其中所有的future都完成此future才算完成。 |
anyOf(...) | 回傳一個future,其中任何一個future完成則此future就算完成。 |
Android N 才能使用Java 8
public static void main(String[] args) {
List<Task> taskList = new ArrayList<>();
taskList.add(new Task("task 1"));
taskList.add(new Task("task 2"));
taskList.add(new Task("task 3"));
Observable.from(taskList)
.subscribe(new Observer<Task>() {
private boolean isTaskSuccess = true;
@Override
public void onCompleted() {
System.out.println("completed");
}
@Override
public void onError(Throwable e) {
System.out.println("error");
}
@Override
public void onNext(Task task) {
try {
if(!task.call() || !isTaskSuccess){
isTaskSuccess = false;
System.out.println(task.getName() + " failed.");
} else {
System.out.println(task.getName() + " success.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private static class Task implements Callable<Boolean>{
private String name;
public Task(String name){
this.name = name;
}
public String getName(){return name;}
@Override
public Boolean call() throws Exception {
return handleTask(name);
}
}
public static boolean handleTask(String task){
if(task.equals("task 3")){return false;}
return true;
}
輸出結果
task 1 fail
task 2 fail
task 3 fail
if(task == 1){return false;}
if(task == 2){return false;}
輸出結果
task 1 success
task 2 fail
task 3 fail
if(task == 3){return false;}
輸出結果
task 1 success
task 2 success
task 3 fail
Async framework
FutureKit
FutureLib