Callable
用法与Runnable相似,但是有返回值
/**
* A task that returns a result and may throw an exception.
* Implementors define a single method with no arguments called
* {@code call}.
*
* <p>The {@code Callable} interface is similar to {@link
* java.lang.Runnable}, in that both are designed for classes whose
* instances are potentially executed by another thread. A
* {@code Runnable}, however, does not return a result and cannot
* throw a checked exception.
*
* <p>The {@link Executors} class contains utility methods to
* convert from other common forms to {@code Callable} classes.
*
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> the result type of method {@code call}
*/
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Future
用于封装Callable的返回值
/**
* A {@code Future} represents the result of an asynchronous
* computation. Methods are provided to check if the computation is
* complete, to wait for its completion, and to retrieve the result of
* the computation. The result can only be retrieved using method
* {@code get} when the computation has completed, blocking if
* necessary until it is ready. Cancellation is performed by the
* {@code cancel} method. Additional methods are provided to
* determine if the task completed normally or was cancelled. Once a
* computation has completed, the computation cannot be cancelled.
* If you would like to use a {@code Future} for the sake
* of cancellability but not provide a usable result, you can
* declare types of the form {@code Future<?>} and
* return {@code null} as a result of the underlying task.
* ...此处省略一万字
**/
public interface Future<V> {}
Example
Callable和Future的Example
import java.util.concurrent.*;
public class T03_Callable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<String> c = () -> "Hello Callable";
ExecutorService service = Executors.newCachedThreadPool();
Future<String> future = service.submit(c); //异步
System.out.println(future.get());//阻塞
service.shutdown();
}
}
FutureTask
Runnable和Future的结合。
FutureTask实现了RunnableFuture接口
public class FutureTask<V> implements RunnableFuture<V> {}
RunnableFuture接口又继承了Runnable和Future接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
Example
import java.util.concurrent.*;
public class T06_00_Future {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Integer> task = new FutureTask<>(()->{
TimeUnit.MILLISECONDS.sleep(500);
return 1000;
}); //new Callable () { Integer call();}
new Thread(task).start();
System.out.println(task.get()); //阻塞
}
}
使用 Future 模拟烧水泡茶
流程:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
public class TestFuture {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建任务T2的FutureTask
FutureTask<String> ft2
= new FutureTask<>(new T2Task());
// 创建任务T1的FutureTask
FutureTask<String> ft1
= new FutureTask<>(new T1Task(ft2));
// 线程T2执行任务ft2
Thread T2 = new Thread(ft2);
T2.start();
// 线程T1执行任务ft1
Thread T1 = new Thread(ft1);
T1.start();
// 等待线程T1执行结果
System.out.println(ft1.get());
}
// T1Task需要执行的任务:
// 洗茶壶、洗茶杯、拿茶叶、泡茶
static class T1Task implements Callable<String> {
FutureTask<String> ft2;
// T1任务需要T2任务的FutureTask
T1Task(FutureTask<String> ft2) {
this.ft2 = ft2;
}
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(1);
System.out.println("T1:洗茶壶...");
TimeUnit.SECONDS.sleep(1);
System.out.println("T1:洗茶杯...");
TimeUnit.SECONDS.sleep(2);
System.out.println("T1:拿茶叶...");
TimeUnit.SECONDS.sleep(1);
// 获取T2线程的开水
String tf = ft2.get();
System.out.println(tf);
System.out.println("T1:泡茶...");
return "上茶";
}
}
// T2Task需要执行的任务:
// 洗水壶、烧开水
static class T2Task implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("T2:洗水壶...");
TimeUnit.SECONDS.sleep(1);
System.out.println("T2:烧开水...");
TimeUnit.SECONDS.sleep(15);
return "T2:水烧开了";
}
}
}
输出:
T2:洗水壶...
T2:烧开水...
T1:洗茶壶...
T1:洗茶杯...
T1:拿茶叶...
T2:水烧开了
T1:泡茶...
上茶