并发之-Callable 和 Future 使用

并发之-Callable 和 Future 使用

Future模式非常适合之处理耗时比较长的业务上使用,可以有效的节省系统响应时间。提高服务器的吞吐量

Callable
Callable与Runnable的功能大致相似,Callable中有一个call()函数,但是call()函数有返回值,而Runnable的run()函数不能将结果返回给客户程序。Callable的声明如下 :


public interface Callable<V> {  

    V call() throws Exception;  
} 

可以看到,这是一个泛型接口,call()函数返回的类型就是客户程序传递进来的V类型。Executor就是Runnable和Callable的调度容器,Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果( Future简介 )。Future声明如下:

public interface Future<T>  
{  
    V get() throws ...;  
    V get(long timeout, TimeUnit unit) throws ...;  
    void cancle(boolean mayInterrupt);  
    boolean isCancelled();  
    boolean isDone();  
}  

使用代码事例:

package com.huilong.study.apple.service.executor;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * @author zhanghuilong
 * @version V1.0
 * @desc
 * @since 2018/01/14
 */
public class StudyFuture implements Callable<String> {
    private String param;

    public StudyFuture(String param){
        this.param = param;
    }

    /**
     * 这里是真实的业务逻辑,其执行可能很慢
     */
    @Override
    public String call() throws Exception {
        //模拟执行耗时
        Thread.sleep(5000);
        String result = this.param + "处理完成";
        return result;
    }

    //主控制函数
    public static void main(String[] args) throws Exception {
        String queryStr = "query";
        //构造FutureTask,并且传入需要真正进行业务逻辑处理的类,该类一定是实现了Callable接口的类
        FutureTask<String> future = new FutureTask<String>(new StudyFuture(queryStr));

        FutureTask<String> future2 = new FutureTask<String>(new StudyFuture(queryStr));
        //创建一个固定线程的线程池且线程数为2,
        ExecutorService executor = Executors.newFixedThreadPool(2);
        //这里提交任务future,则开启线程执行RealData的call()方法执行
        //submit和execute的区别: 第一点是submit可以传入实现Callable接口的实例对象, 第二点是submit方法有返回值

        Future f1 = executor.submit(future);        //单独启动一个线程去执行的
        Future f2 = executor.submit(future2);
        System.out.println("一些其他请求开始执行。。。");

        try {
            //这里可以做额外的数据操作,也就是主程序执行其他业务逻辑,相当费时的业务
            System.out.println("开始处理实际的业务逻辑...");
            Thread.sleep(1000);

        } catch (Exception e) {
            e.printStackTrace();
        }
        //调用获取数据方法,如果call()方法没有执行完成,则依然会进行等待
        System.out.println("数据:" + future.get());
        System.out.println("数据:" + future2.get());

        executor.shutdown();
    }
}

猜你喜欢

转载自blog.csdn.net/java_huilong/article/details/79056985