先来看一下简单的程序
public class ConcurrencyTaskFuture {
public static void main(String[] args) throws Exception {
FutureTask<String> futureTask = new FutureTask<>(()->{
System.out.println("煮米饭");
TimeUnit.SECONDS.sleep(10);
return "米饭煮好了";
});
FutureTask<String> futureTask1 = new FutureTask<>(() -> {
System.out.println("开始洗菜");
TimeUnit.SECONDS.sleep(2);
System.out.println("开始炒菜");
TimeUnit.SECONDS.sleep(2);
return " 菜做好了";
});
FutureTask<String> futureTask2 = new FutureTask<>(() -> {
String f1 = futureTask.get();
String result2 = futureTask1.get();
System.out.println(f1+":"+result2);
return "开始吃饭。。。";
});
Thread thread1 = new Thread(futureTask);
Thread thread2 = new Thread(futureTask1);
Thread thread3 = new Thread(futureTask2);
thread1.start();
thread2.start();
thread3.start();
System.out.println(futureTask2.get());
}
}
看完上面的例子我们再来给你简单的介绍一下其中一些细节部分先来看FutureTask
构造方法
/**
* Creates a {@code FutureTask} that will, upon running, execute the
* given {@code Callable}.
*
* @param callable the callable task
* @throws NullPointerException if the callable is null
*/
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
/**
* Creates a {@code FutureTask} that will, upon running, execute the
* given {@code Runnable}, and arrange that {@code get} will return the
* given result on successful completion.
*
* @param runnable the runnable task
* @param result the result to return on successful completion. If
* you don't need a particular result, consider using
* constructions of the form:
* {@code Future<?> f = new FutureTask<Void>(runnable, null)}
* @throws NullPointerException if the runnable is null
*/
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
Executors.callable
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
继续看一下
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
它对Runnaable接口做了一次封装 这里用到了适配器模式。
在第一个程序当中我们使get来获取程序执行的结果
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
/**
* @throws CancellationException {@inheritDoc}
*/
public V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
if (unit == null)
throw new NullPointerException();
int s = state;
if (s <= COMPLETING &&
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
throw new TimeoutException();
return report(s);
}
程序中有两个重载的Get方法一个是指定时间的,一个是不指定时间的 ,get方法会阻塞当前的线程执行,在制定的时间内,如果没有制定则是一直等待。