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 {
@Test
public void test1() throws InterruptedException, ExecutionException{
FutureTask f = new FutureTask<String>(new SimpleCallable());
f.run();
String s = f.get().toString();
System.out.println(s);
}
@Test
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{
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "abc123";
}
}
class SimpleRunnable implements Runnable{
@Override
public void run() {
int i = 1/2;
//int i = 1/0;
}
}