1. Callable
源码:public FutureTask(Callable<V> callable) {
if (callable == null) throw new NullPointerException(); this.callable = callable; this.state = NEW; // ensure visibility of callable}
Callable接口:与Runnable接口区别在于,call()方法可以返回执行结果,而Runnable接口的run方式不行的。
实现Callable接口的类无法提供给Thread使用,所以想通过Thread的方式直接来获得线程执行返回的值是不行的,可以通过FutureTask做一层封装。
FutureTask构造函数传入Callable实现类,使用FutureTask.get()得到线程真正执行结果返回值
2.Runnable
源码:
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result); this.state = NEW; // ensure visibility of callable }FutureTask构造函数传入Runnable实现类,使用FutureTask.get()得到传入参数result的值,该值可以用来判断线程是否正常执行等,无法通过它来得到线程执行想要返回的结果。
既然传入的Runnable,为什么还能得到result值喃,因为在Executors.callable(runnable, result)里面使用RunnableAdapter将Runnable封装成了Callable,result值传给了RunnableAdapter.result,然后线程执行call()方法后,原封不动的返回RunnableAdapter.result。
写的一段测试代码:
package com.jv.parallel.futuretask;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask;import org.junit.Test;
public class TestFutureTask {
public void test1() throws InterruptedException, ExecutionException{ FutureTask f = new FutureTask<String>(new SimpleCallable()); f.run(); String s = f.get().toString(); System.out.println(s); } public void test2() throws InterruptedException, ExecutionException{ String flag="123"; FutureTask f = new FutureTask<String>(new SimpleRunnable(),flag); f.run(); String s = f.get().toString(); System.out.println("s:"+s); } }class SimpleCallable implements Callable{
public String call() throws Exception { // TODO Auto-generated method stub return "abc123"; } } class SimpleRunnable implements Runnable{
public void run() { int i = 1/2; //int i = 1/0; } }