CompletionService
1.1 CompletionService 的功能
CompletionService的功能就是以異步的方式,一邊產生新的任務,一邊處理已完成任務的結果。
CompletionService主要解決一個什麼問題呢?
Future 接口調用get()方法取得處理的結果,但是這個方法是阻塞性的,如果調用get()
方法時,任務尚未執行完成,get方法會一直阻塞到此任務執行完成爲止。這樣的後果就是一旦前面
的任務耗時太長,後面的任務的get()方法就會排隊等待,影響相率。
使用CompletionService可以按照完成這些任務的時間順序處理他們的結果。
1.2 代碼
package com.lhc.concurrent.completion.nonBlock;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.concurrent.*;
public class MyCallable implements Callable<String>{
private String userName;
private long sleepTime;
public MyCallable(String userName, long sleepTime) {
this.userName = userName;
this.sleepTime = sleepTime;
}
@Override
public String call() throws Exception {
System.out.println(userName);
Thread.sleep(sleepTime);
return "return " + sleepTime;
}
public static void main(String[] args) throws Exception{
MyCallable name1 = new MyCallable("name1", 1050);
MyCallable name2 = new MyCallable("name2", 1040);
MyCallable name3 = new MyCallable("name3", 1030);
MyCallable name4 = new MyCallable("name4", 1020);
MyCallable name5 = new MyCallable("name5", 1010);
ArrayList<Callable> callables = Lists.newArrayList();
callables.add(name1);
callables.add(name2);
callables.add(name3);
callables.add(name4);
callables.add(name5);
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 5,
TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
ExecutorCompletionService completionService = new ExecutorCompletionService(executor);
for (int i = 0; i < callables.size(); i++) {
completionService.submit(callables.get(i));
}
for (int i = 0; i < 5; i++){
/**
* 哪個任務先執行完,那個任務的返回值就先打印,解決了Future 阻塞的特點
* 但是如果沒有任何任務被執行完,則.take().get()方法還是呈阻塞特性。
*/
System.out.println(completionService.take().get());
}
}
}
1.3測試結果
name1
name5
name2
name3
name4
return 1010
return 1020
return 1030
return 1040
return 1050
2.1 Future submit(Runnable task, V result)方法
另外一種使用姿勢
2.2 代碼
public class User {
private String name;
private String password;
public User(String name, String password) {
super();
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.lhc.concurrent.completion.submit;
import java.util.concurrent.*;
public class MyRunnable implements Runnable{
private User user;
public MyRunnable(User user) {
super();
this.user = user;
}
@Override
public void run() {
user.setName("jt");
user.setPassword("pwd");
System.out.println("running end");
}
public static void main(String[] args) throws Exception{
User user = new User("name", "pwd");
MyRunnable myRunnable = new MyRunnable(user);
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
Future<User> submit = completionService.submit(myRunnable, user);
System.out.println(submit.get().getName() + " " + submit.get().getPassword());
}
}
2.3 運行結果
running end
jt pwd