Java 5.0 在 java.util.concurrent 提供了一个新的创建执行线程的方式: 实现 Callable 接口。
Callable 接口类似于 Runnable,但是 Runnable 不会返回结果,并且无法抛出经过检查的异常,而 Callable 依赖 FutureTask 类获取返回结果。
没有使用线程池:
代码演示:
public class CallableTest {
public static void main(String[] args) throws Exception {
MyThread mt = new MyThread();
FutureTask<Integer> result = new FutureTask<Integer>(mt);
new Thread(result).start();
// 获取运算结果是同步过程,即 call 方法执行完成,才能获取结果
Integer sum = result.get();
System.out.println(sum);
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
单个线程池: 使用ExecutorService、Callable、Future实现有返回结果的线程
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
public class MyCallable implements Callable<String> {
/**
* 实现call方法,接口中抛出异常。因为子类不可以比父类干更多的坏事,所以子类可以不抛出异常
*/
@Override
public String call() {
System.out.println(Thread.currentThread().getName() + " 执行callable的call方法");
return "result";
}
public static void main(String[] args) {
test1();
}
/**
* 单个线程
*/
public static void test1() {
// 1.创建固定大小的线程池
ExecutorService es = Executors.newFixedThreadPool(1);
// 2.提交线程任务,用Future接口接受返回的实现类
Future<String> future = es.submit(new MyCallable());
// 3.关闭线程池
es.shutdown();
// 4.调用future.get()获取callable执行完成的返回结果
String result;
try {
result = future.get();
System.out.println(Thread.currentThread().getName() + "\t" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
结果:
结果:
pool-1-thread-1 执行callable的call方法
main result
多个线程的执行返回结果:
public class MyCallable implements Callable<String> {
/**
* 实现call方法,接口中抛出异常。因为子类不可以比父类干更多的坏事,所以子类可以不抛出异常
*/
@Override
public String call() {
System.out.println(Thread.currentThread().getName() + " 执行callable的call方法");
return "result";
}
public static void main(String[] args) {
test2();
}
/**
* 多个线程
*/
public static void test2() {
// 1.创建固定大小的线程池(5个)
int threadNum = 5;
ExecutorService es = Executors.newFixedThreadPool(threadNum);
// 2.提交线程任务,用Future接口接受返回的实现类
List<Future<String>> futures = new ArrayList<Future<String>>(threadNum);
for (int i = 0; i < threadNum; i++) {
Future<String> future = es.submit(new MyCallable());
futures.add(future);
}
// 3.关闭线程池
es.shutdown();
// 4.调用future.get()获取callable执行完成的返回结果
for (Future<String> future : futures) {
try {
String result = future.get();
System.out.println(Thread.currentThread().getName() + "\t" + result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
结果:
pool-1-thread-1 执行callable的call方法
pool-1-thread-2 执行callable的call方法
pool-1-thread-4 执行callable的call方法
pool-1-thread-3 执行callable的call方法
main result
pool-1-thread-5 执行callable的call方法
main result
main result
main result
main result