并发之-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();
}
}