我们在使用多线程处理数据,从而避免CPU资源的过剩的时候,要怎么获取线程结果呢,这就要用到FutureTask和Callable了,由于网络上相关的介绍太多了,这里不再一一赘述,只介绍如何使用它们.
1.▼继承Callable接口,创建业务逻辑线程 ThreadTest,重写其中的call()方法,可以看到Callable的泛型可以是任何类型Object;
public class ThreadTest implements Callable<Object>{
private CountDownLatch cdl;
public ThreadTest(CountDownLatch cdl){
this.cdl = cdl;
}
@Override
public Object call() throws Exception {
//线程处理代码,此处省略
//线程执行完毕 计数器-1 一般放在 finally代码块中 避免线程卡死
cdl.countDown();
return Object;
}
}
2.▼创建测试类,开启线程
//这里可以创建集合将开启的线程放入集合中,方便处理完成获取结果
List<FutureTask<Object>> threadList = new ArrayList();
//存放所有线程的执行结果
List<Object> resultList = new ArrayList();
//创建一个固定线程的线程池
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(50);
//计数器
CountDownLatch cdl = new CountDownLatch(50);
for(int i=0;i<50;i++){//开启50条线程
//使用FutureTask创建线程
FutureTask<Object> task = new FutureTask(new ThreadTest(cdl));
threadList.add(task);
threadPool.execute(task);
//Object result = task.get();
}
//阻塞主线程直到所有子线程执行完毕
cld.await();
for(int i=0;i<threadList.size();i++){
//获取每个线程执行的结果
resultList.add(threadList.get(i).get());
}
需要注意的是,FutureTask中的get()方法会阻塞线程,直到此条线程执行完成返回执行结果,如果我们在以上代码的第一个for循环中使用get()方法,那么多线程将毫无意义,因为下一个线程一定会等此次线程执行完才会开启
欢迎关注我的微信公众号 "抓几个娃", 一起聊聊技术和生活
以上