java中执行耗时任务,有时需要线程池、Callable、Future结合使用
- Callable类
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class MyCallable implements Callable<Boolean> {
private int no;
public MyCallable(int no) {
this.no = no;
}
@Override
public Boolean call() throws Exception {
int sleep = new Random().nextInt(15);
TimeUnit.SECONDS.sleep(sleep);
System.out.printf("task #%02d, sleep %ds, ok!\n", no, sleep);
return Boolean.TRUE;
}
}
- Main方法
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
// List<Future<Boolean>> list = new ArrayList<>();
CompletionService<Boolean> cs = new ExecutorCompletionService<>(pool);
for (int i = 0; i < 15; i++) {
final int j = i;
// list.add(pool.submit(new MyCallable(j)));
cs.submit(new MyCallable(j));
}
// for (Future<Boolean> future : list) {
// try {
// future.get();
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
for (int i = 0; i < 15; i++) {
try {
cs.take().get();
} catch (Exception e) {
e.printStackTrace();
}
}
pool.shutdown();
}
}
- 执行结果如下

- 结论:
future.get();为非阻塞,不会阻塞其它线程执行