Callable是一个接口,用于创建有返回值的线程。相对地,一般我们会实现Runnable接口去构造一个Thread,但是Runnable是没有返回值的。在此记录一下Callable的用法。
比如,我想要在线程执行任务完毕之后,返回一个Integer,那么可以有以下几种方式:
1.如果你用的是new Thread()的方式创建线程,那么可以用FutureTask:
public class TestAsync {
/**
* 获取当前线程的id
*
* @return
*/
public static long getCurrentThreadId() {
return Thread.currentThread().getId();
}
public static void main(String[] args) {
FutureTask<Integer> futureTask = new FutureTask<Integer>(
new Callable<Integer>() {
public Integer call() throws Exception {
/**
* 模拟耗时操作
*/
Thread.sleep(4000);
System.out.println("线程id为" + getCurrentThreadId() + ": sleep结束……");
return 100; // 随便返回一个数
}
});
/**
* 注意,子线程是从这里就开始执行了,而不是当调用get()取结果的时候才执行
*/
new Thread(futureTask).start();
Integer i = null;
try {
System.out.println("线程id为" + getCurrentThreadId() + ": 开始取结果……");
/**
* get()会阻塞相应的线程,直到有结果返回 按照上面的写法,将会阻塞4秒,然后继续进行在它下面的语句
*/
i = futureTask.get();
System.out.println("线程id为" + getCurrentThreadId() + ": 取到结果了");
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
System.out.println("返回的结果为:" + i);
}
}
2.(推荐)如果用的是线程池对应的ExecutorService接口,那么可以用Future类:
提醒一点,ExecutorService要用submit+Callable的形式才能返回,而不用execute
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
Future<Integer> future = service.submit(new Callable<Integer>() {
public Integer call() throws Exception {
/**
* 模拟耗时操作
*/
System.out.println("线程id为" + getCurrentThreadId() + ": sleep……");
Thread.sleep(4000);
return 100; // 随便返回一个数
}
});
try {
System.out.println(future.get());
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}