如何统一处理线程池返回的结果
在读这篇文章之前,有些基础需要提前了解一下!
首先要了解的是什么是线程池,还有什么是线程回调,下方有我两个博客链接,讲的是什么是线程池,和什么是线程回调,所以在往下读之前最好事先了解一下在往下阅读。
1、线程池链接:
2、线程回调链接
线程池顾名思义可以理解为提前创建若干个线程,若有任务时,线程池里的线程就会处理任务,任务处理完之后线程并不会被销毁,而是等待下一个任务。由于创建和销毁线程都是消耗系统资源的,所以当你想要频繁的创建和销毁线程的时候就可以考虑使用线程池来提升系统的性能。
线程池的含义百度上有很多,这里就不细讲了。
在说如何统一处理返回的结果,讲之前在这里有个问题需要我们大家来考虑,就是通过线程回调返回来的结果是属于未来结果,而且在线程池里的线程,它并不属于单线程,多线程有时候并不好控制,我个人的解决办法是:
1、首先通过队列将线程池中线程返回的结果收集起来
2、之后在做统一处理
这只是我个人的处理办法而已,也许会有更好的解决方案,举例:比如不做线程回调,将结果放进redis队列啊,之后在做统一处理等等,方法很多,不过在这里并不是我要讲的,如果有兴趣,大家可以慢慢研究。
接下来就是干货了。
我首先做了个单例队列用来存储线程返回的未来结果用。
上代码:
public class ListDL {
private static ConcurrentLinkedDeque<Future<String>> list = null;
static {
new ListDL();
}
public ListDL() {
ListDL.list = new ConcurrentLinkedDeque<Future<String>>();
}
//唯一实例
public static class SingletonHolder{
public static ConcurrentLinkedDeque<Future<String>> instance() {
return ListDL.list;
}
}
//获取该实例
public static ConcurrentLinkedDeque<Future<String>> getInstance(){
return SingletonHolder.instance();
}
}
在我们的代码里,将线程池返回的未来结果放进队列中,在这里我用的是定长线程池,详细的可以看我上方的博客。
ExecutorService executorService = Executors.newFixedThreadPool(30);
Future<String> submit = executorService.submit(new MyTaskOne(redisVauleModel));
ListDL.getInstance().addLast(submit);
这里的MyTaskOne就是一个实现Callable<T>的回调线程类,详细的可以看我的回调线程的博客,
最后要说的就是统一处理的部分了
while(true){
Future<String> first = ListDL.getInstance().getFirst();
if (first.isDone()) { //保证任务执行完删除队列
//这里抓取数据或做业务处理
ListDL.getInstance().removeFirst();//在队列里删除该结果
}
}
以上就是我的解决思路了,可能并不完善,毕竟是我个人的,如有错误处,多多保函。