Java线程池之FutureTask【Java线程池系列3】
在附录的文章2中,使用了Java的线程池和Future、Callable。本篇文章在文章2的基础上加以改进,基于FutureTask,换掉Future重新实现。
FutureTask既实现了Future,也实现了Runnable,所以更加的普适,用法和Future相类似。和附录的文章2代码写法类似,比如:
package test_java;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class ZhangPhilExecutorService {
private final int POOL_SIZE = 5;
private final int TOTAL_THREAD = 6;
public ZhangPhilExecutorService() {
// 创建容量为 POOL_SIZE 的线程池。
ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);
final ArrayList<FutureTask<String>> futures = new ArrayList<FutureTask<String>>();
for (int i = 0; i < TOTAL_THREAD; i++) {
AThread t = new AThread(i);
//在此处使用FutureTask实现,注意写法
FutureTask<String> futureTask = new FutureTask<String>(t);
futures.add(futureTask);
pool.submit(futureTask);
}
System.out.println("获取结果中...");
for (FutureTask<String> f : futures) {
try {
// if (f.isDone())
System.out.println(f.get());
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("得到全部结果.");
// 关闭线程池。
pool.shutdown();
}
private class AThread implements Callable<String> {
private int id;
public AThread(int id) {
this.id = id;
}
@Override
public String call() {
System.out.println("线程:" + id + " -> 运行...");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程:" + id + " -> 结束");
return "返回的字符串" + id;
}
}
public static void main(String[] args) {
new ZhangPhilExecutorService();
}
}
注意,FutureTask和Future在get返回值时候,都将阻塞,所以,为了避免阻塞,可以加一条判断语句isDone,完成了才get,否则不予get。另外,FutureTask还有Future在get的时候,还有一个相类似的方法体:
public V get(long timeout,TimeUnit unit);
可以设置超时时间,那么在get时候如果超时则返回,从另外一个途径实现非阻塞获取返回数据。
附录我以前写的相关文章:
【文章1】《Java线程池:ExecutorService,Executors》链接地址:http://blog.csdn.net/zhangphil/article/details/43898637
【文章2】《Java线程池及Future、Callable获得线程返回结果【Java线程池系列2】》链接地址:http://blog.csdn.net/zhangphil/article/details/49701219