并发编程(二) Future

并发编程(二) Future

1.1 Future是什么?

异步任务中我们需要知道的两个重要属性是

  • 任务什么时候结束?
  • 任务的结果是什么?

ThreadPoolExecutor提交任务的方法有如下几个:

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
void execute(Runnable command);

其中execute方法是没有返回值的。

submit有三个重构方法。两个又返回值的对象都是Future对象,通过Future的方法我们就可以获取任务执行的状态和结果。Future的五个方法如下:

/**
* 取消任务
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 任务是否被取消
*/
boolean isCancelled();
/**
* 任务是否完成
*/
boolean isDone();
/**
* 获取任务的结果
*/
V get() throws InterruptedException, ExecutionException;
/**
* 获取任务的结果,支持超时机制,规定的时间获取不到结果,就不再阻塞线程
*/
V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;

1.2 Future的使用

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
void execute(Runnable command);

其中execute方法是没有返回值的。

submit有三个重构方法。两个又返回值的对象都是Future对象,通过Future的方法我们就可以获取任务执行的状态和结果。Future的五个方法如下:

/**
* 取消任务
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 任务是否被取消
*/
boolean isCancelled();
/**
* 任务是否完成
*/
boolean isDone();
/**
* 获取任务的结果
*/
V get() throws InterruptedException, ExecutionException;
/**
* 获取任务的结果,支持超时机制,规定的时间获取不到结果,就不再阻塞线程
*/
V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;

1.2 Future的使用

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
void execute(Runnable command);

其中execute方法是没有返回值的。

submit有三个重构方法。两个又返回值的对象都是Future对象,通过Future的方法我们就可以获取任务执行的状态和结果。Future的五个方法如下:

/**
* 取消任务
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* 任务是否被取消
*/
boolean isCancelled();
/**
* 任务是否完成
*/
boolean isDone();
/**
* 获取任务的结果
*/
V get() throws InterruptedException, ExecutionException;
/**
* 获取任务的结果,支持超时机制,规定的时间获取不到结果,就不再阻塞线程
*/
V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;

1.2 Future的使用

下边代码分别是submit的三个重载方法饿使用。

/**
 *
 * @author: zy
 * @Date: 2019-06-26 16:52
 * @Copyright: 2019 www.lenovo.com Inc. All rights reserved.
 */
public class ExecutorDemo1 {
    public static void main(String[] args) throws Exception{
        Future<String> f1 = TestThreadPool.getInstance().submit(() -> {
            System.out.println("11111");
            return "hello concurrent";
        });


        Future f2 = TestThreadPool.getInstance().submit(() -> {
            System.out.println("22222");
        });
        Result result = new Result();
        TestThreadPool.getInstance().submit(new Task(result),result);
        System.out.println(result.getName());
        String s = f1.get();
        System.out.println(s);
        System.out.println(f2.get());
    }
}
class Task implements Runnable{
    private Result result;

    Task(Result result){
        this.result = result;
    }
    @Override
    public void run(){
        System.out.println("task-------");
        result.setName("task------");
    }
}
class Result{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

1.3 Future 实现下面条程序

直接上代码:

/**
 *
 * @author:zy
 * @Date: 2019-06-26 16:52
 * @Copyright: 2019 www.lenovo.com Inc. All rights reserved.
 */
public class CookAMeal {
    public static void main(String[] args)throws  Exception{

        Task1 task1 = new Task1();
        Future<String> task1Future = TestThreadPool.getInstance().submit(new Task1());

        Future task2Future = TestThreadPool.getInstance().submit(new Task2(task1Future));
        System.out.println(task2Future.get());
    }
}

/**
 * 刷碗 准备面条
 */
 class Task1 implements Callable<String>{


    @Override
    public String call() throws Exception {

        System.out.println("刷碗-----");
        TimeUnit.SECONDS.sleep(1);

        System.out.println("准备面条-----");
        TimeUnit.SECONDS.sleep(1);

        return "龙须面";
    }
}


/**
 * 刷锅  烧水 下面条
 */
class Task2 implements Callable{

    private Future future;

    Task2(Future future){
        this.future = future;
    }

    @Override
    public Object call() throws Exception {

        System.out.println("刷锅-----");
        TimeUnit.SECONDS.sleep(1);

        System.out.println("烧水-----");
        TimeUnit.SECONDS.sleep(1);

        Object nodeKind = future.get();

        return "煮面条---"+nodeKind;
    }
}

一共是两个任务,第一个任务负责刷碗,准备面条。第二个任务负责刷锅,烧水,下面条,需要注意的是下面条的操作是需要等待面条准备完成之后才可以执行的,就是线程相互之间的时序关系。

Future可以获取线程的执行结果,所以当线程之间有依赖关系的情况下Future可以轻松的解决这种问题。

猜你喜欢

转载自blog.csdn.net/weixin_39034379/article/details/93792615