线程池,想必无论是做Android开发的还是做Java开发的对它都不陌生。它可以为我们提高线程的复用,默认情况下核心线程不会被销毁,避免了我们创建和销毁线程带来的开销。也可以为线程设置超时时间,超时才会被销毁。
那我们如何去知道线程池中的任务执行完毕了呢?并且获取任务的执行结果呢?
下面自己写一个类包装我们线程池,实现我们的需求。
下面动手实现以下我们的代码:
首先我们创建一个类MyCompleteExecutorService,在它内部我们定义几个成员变量:
//持有的线程池实例
private ExecutorService executorService;
//用来记录任务执行完成的数量
private AtomicInteger alreadyFinishNum;
//存储我们的任务结果
private ArrayMap<K, V> arrayMap;
//记录任务的总数
private int taskNum;
定义我们的构造方法:
public MyCompleteExecutorService(ExecutorService executorService) {
this.mExecutorService = executorService;
//初始化计数器
this.mAlreadyFinishNum = new AtomicInteger(0);
}
接下来我们在内部定义两个提交任务的方法,方法内部我们调用线程池提交任务的方法:
/**
* 提交Callable任务
* @param tag
* @param task
*/
public void submitTask(K tag ,MyCallable<K,V> task) {
task.setKey(tag);
taskNum++;
mExecutorService.submit(task);
}
/**
* 提交Runnable任务
* @param runnable
*/
public void submitTask(MyRunnable runnable) {
taskNum++;
mExecutorService.submit(runnable);
}
定义我们自己的任务类分别继承自Callable和Runnable,
在两个类中,分别持有外部类的弱引用。当任务执行完成我们把已完成的任务计数器+1,如果有返回结果,我们就把返回结果放入我们的mResultMap中。
/**
* 继承Callable
*/
public static abstract class MyCallable<K,V> implements Callable<V> {
//持有外部类的弱引用
private WeakReference<MyCompleteExecutorService> mWeakService;
//任务标识
private K key;
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public MyCallable(MyCompleteExecutorService myCompleteExecutor) {
mWeakService = new WeakReference<>(myCompleteExecutor);
}
@Override
public V call() throws Exception {
if(mWeakService.get().mResultMap==null){
mWeakService.get().mResultMap = new ArrayMap();
}
//获取我们的返回结果
V result = doMyCall();
//任务执行结果放入Map中存储起来
mWeakService.get().mResultMap.put(key,result);
//计数器+1
mWeakService.get().addFinishNum();
return result;
}
/**
* 子类必须实现这个方法
* @return
*/
protected abstract V doMyCall();
}
/**
* 继承Runnable
*/
public static abstract class MyRunnable implements Runnable {
private WeakReference<MyCompleteExecutorService> mWeakService;
public MyRunnable(MyCompleteExecutorService myCompleteExecutor) {
mWeakService = new WeakReference<>(myCompleteExecutor);
}
@Override
public void run() {
doMyRunnable();
if (mWeakService.get() != null) {
//计数器+1
mWeakService.get().addFinishNum();
}
}
/**
* 子类必须实现的方法
*/
protected abstract void doMyRunnable();
}
我们的计数器+1的方法:
private void addFinishNum() {
mAlreadyFinishNum.incrementAndGet();
if (mAlreadyFinishNum.get() == taskNum) {
//全部完成
if (taskCallback != null) {
//执行接口方法
taskCallback.alreadyFinishAllTask(taskNum);
}
}
}
定义我们的回调接口:
public interface FinishTaskCallback {
void alreadyFinishAllTask(int finishNum);
}
private FinishTaskCallback taskCallback;
public FinishTaskCallback getTaskCallback() {
return taskCallback;
}
public void setTaskCallback(FinishTaskCallback taskCallback) {
this.taskCallback = taskCallback;
}
完整代码实现如下:
public class MyCompleteExecutorService<K, V> {
//持有的线程池实例
private ExecutorService mExecutorService;
//用来记录任务执行完成的数量
private AtomicInteger mAlreadyFinishNum;
//存储我们的任务结果
private ArrayMap<K, V> mResultMap;
//记录任务的总数
private int taskNum;
public ArrayMap<K, V> getArrayMap() {
return mResultMap;
}
public MyCompleteExecutorService(ExecutorService executorService) {
this.mExecutorService = executorService;
this.mAlreadyFinishNum = new AtomicInteger(0);
}
/**
* 提交Callable任务
* @param tag
* @param task
*/
public void submitTask(K tag ,MyCallable<K,V> task) {
task.setKey(tag);
taskNum++;
mExecutorService.submit(task);
}
/**
* 提交Runnable任务
* @param runnable
*/
public void submitTask(MyRunnable runnable) {
taskNum++;
mExecutorService.submit(runnable);
}
/**
* 继承Callable
*/
public static abstract class MyCallable<K,V> implements Callable<V> {
//持有外部类的弱引用
private WeakReference<MyCompleteExecutorService> mWeakService;
//任务标识
private K key;
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public MyCallable(MyCompleteExecutorService myCompleteExecutor) {
mWeakService = new WeakReference<>(myCompleteExecutor);
}
@Override
public V call() throws Exception {
if(mWeakService.get().mResultMap==null){
mWeakService.get().mResultMap = new ArrayMap();
}
//获取我们的返回结果
V result = doMyCall();
//任务执行结果放入Map中存储起来
mWeakService.get().mResultMap.put(key,result);
//计数器+1
mWeakService.get().addFinishNum();
return result;
}
/**
* 子类必须实现这个方法
* @return
*/
protected abstract V doMyCall();
}
/**
* 继承Runnable
*/
public static abstract class MyRunnable implements Runnable {
private WeakReference<MyCompleteExecutorService> mWeakService;
public MyRunnable(MyCompleteExecutorService myCompleteExecutor) {
mWeakService = new WeakReference<>(myCompleteExecutor);
}
@Override
public void run() {
doMyRunnable();
if (mWeakService.get() != null) {
//计数器+1
mWeakService.get().addFinishNum();
}
}
/**
* 子类必须实现的方法
*/
protected abstract void doMyRunnable();
}
/**
* 计数器+1的操作
*/
private void addFinishNum() {
mAlreadyFinishNum.incrementAndGet();
Log.v("alreadyFinishNum", mAlreadyFinishNum.get() + "");
if (mAlreadyFinishNum.get() == taskNum) {
//全部完成
if (taskCallback != null) {
taskCallback.alreadyFinishAllTask(taskNum);
}
}
}
public interface FinishTaskCallback {
void alreadyFinishAllTask(int taskNum);
}
private FinishTaskCallback taskCallback;
public FinishTaskCallback getTaskCallback() {
return taskCallback;
}
public void setTaskCallback(FinishTaskCallback taskCallback) {
this.taskCallback = taskCallback;
}
}
下面我们测试一下我们写的类:
通过for循环提交十个任务:
myCompleteExecutor = new MyCompleteExecutorService<>(Executors.newFixedThreadPool(10));
//让当前类实现我们的接口
myCompleteExecutor.setTaskCallback(this);
for (int i = 0; i < 10; i++) {
final int finalI1 = i;
myCompleteExecutor.submitTask(i,new MyCompleteExecutorService.MyCallable<Integer, String>( myCompleteExecutor) {
@Override
protected String doMyCall() {
int k = 0;
while (k <10000000) {
k++;
}
//返回任务结果
return String.valueOf(k + finalI1);
}
});
}
实现回调方法,在我们方法中打印结果:
@Override
public void alreadyFinishAllTask(int finishTaskNum) {
if(finishTaskNum!=10){
return;
}
for (int i = 0; i < 10; i++) {
//打印所有任务的执行结果
//注意了这里的方法运行在我们的线程池的线程中,如有需要自行切换
System.out.println("第"+i+"个任务的执行结果是:"+myCompleteExecutor.getArrayMap().get(i));
}
}
打印输入如下:
其实java也为我们内置了一个ExecutorCompletionService类,它里面通过一个阻塞队列存储了所有任务的Future对象,我们可以通过这个Future获取相应任务的执行结果。