import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /*** * Callable的任务执行后可返回值,而Runnable的任务是不能返回值的 * 运行Callable任务可拿到一个Future对象 * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成 * @author huahui */ class TaskWithResult implements Callable<Integer> { int result=1; public Integer call() throws Exception { // TODO 业务代码,返回该线程计算的result结果 for(int i=0;i<5;i++) { Thread.sleep(1000); } return result; } } public class CallableDemo { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService exec = Executors.newCachedThreadPool(); ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(); for(int i=0;i<10;i++) { //开启线程执行 results.add(exec.submit(new TaskWithResult())); } int result = 0; for(Future<Integer> fs:results) { result+=fs.get();//get会阻塞,直到结果准备就绪 } System.out.print(result); } } /* Output:(用时5秒多,就是每个线程都休眠了5秒) * 10 */
如果希望在任务完成时能够返回一个值,可以新建线程的时候记录线程的引用,然后join住线程,取出变量,不过这样有问题
问题1:join住就是伪多线程了
问题2:线程回收?局部变量是否依然能取到
问题3:显示调用start()能join(),如果用ExecutorService就无法有效的阻塞线程了。
解决方式:实现Callable接口,而不是Runnable接口!