Runnable类
Runnable
RunnableFuture
FutureTask
FutureTask(Callable<V> callable)
从这层结构我们可以看出来FutureTask
为我们的Callable
和Thread
扯上关系的一个桥梁,其实就是Runnable
的一个子类
Callable类
Callable
类和我们的Runnable
类其实是一样的,只不它的call
方法带有返回值,也可以抛出异常。
代码演示
之前我们写一个线程我们都是写的Runnable
,只不过现在是替换成Runnable
的子类FutureTask
实现而已,本质还是Runnable
public class LockTest {
public static void main(String[] args) {
DataSource sou = new DataSource();
new Thread(()->{sou.execute();}).start();
//替换Runnable的子类FutureTask实现,并且可以得到返回值
new Thread(new FutureTask<String>(()->{
String name = sou.execute();
System.out.println("name="+name);
return name;
})).start();
}
}
class DataSource {
private String name = "datasoucreField";
public String execute() {
System.out.println("线程执行");
return name;
}
}
我们再来注意两个callable小细节,先看代码
class MyTask implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName()+"call()");
return "hellocallable";
}
}
public class LockTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//现在准备替换Runnable的子类实现FutureTask
FutureTask<String> futureTask = new FutureTask<>(new MyTask());
new Thread(futureTask, "A").start();
new Thread(futureTask, "A").start();
System.out.println(futureTask.get());
}
}
运行结果
Acall()
hellocallable
hellocallable
Process finished with exit code 0
发现Acall()
只是输出了一次,而我们明明是开启了两个线程,按理应该是输出两次Acall()
的,这里是因为FutureTask
会有缓存,提高执行效率,还有一个我们get()
方法时方法会阻塞