在我们对 Scala 的使用过程之中.我们会频繁的用到一类方法,称为异步方法.
在 Scala 中也是我们最熟悉的 scala.concurrent.Future
.不了解相关内容的可以去看 Future
相关的博客.
通过对 Future
方法的调用,我们可以特别优雅的方式实现异步的调用.也就是类似多线程的使用.
在 Java 中,代码大部分都是同步执行的.简单的来说,就是做一顿饭我先刷锅,再淘米.等米饭做熟了再去洗碗洗菜炒菜盛饭盛菜摆桌吃饭.
有了异步方法,我们就可以做到先刷锅刷碗,在淘米做饭的空闲功夫去洗菜炒菜做饭.大大节省我们的程序的运行效率.
FutureTask
是Future
接口的一个实现类,它是从 Java 1.5 开始引入的.通过它能够控制它的执行方法的行为.其具体的内容是通过 Callable
接口来实现的.
FutureTask
有7个状态,其中数值从小到大:NEW
COMPLETING
NORMAL
EXCEPTIONAL
CANCELLED
INTERRUPTING
INTERRUPTED
其中,状态有几个可能的流转方式:
- 新建 -> 完成中 -> 普通
- 新建 -> 完成中 -> 异常
- 新建 -> 取消
- 新建 -> 打断中 -> 打断
FutureTask
有许多方法,包括:
isCancelled
方法 : 返回是否取消(当状态是后面三种情况时)isDone
方法 : 返回是否处理(当状态不是新建时)cancel
方法 : 试图取消方法(状态可能变成取消或者被打断)get
方法 : 获取到方法的返回值,如果传入了时间并且超时的话会抛出异常
FutureTask
的构造器传入一个 Callable
对象,它和 Runnable
的主要区别是:
Callable |
Runnable |
---|---|
实现 call 方法 |
实现 run 方法 |
可获得返回结果 | 不能直接获得结果 |
可以抛出异常 | 不能抛出异常 |
接下来我们直接看代码实现;
首先我有五个获取对应的信息的方法getGeneral
.
123456789101112131415161718192021222324252627282930 |
ExecutorService executorService = Executors.newFixedThreadPool(5);//分别建立了对应的五个异步对象FutureTask<JSONObject> generalA = getGeneral(receiver, MessageType.A);FutureTask<JSONObject> generalB = getGeneral(receiver, MessageType.B);FutureTask<JSONObject> generalC = getGeneral(receiver, MessageType.C);FutureTask<JSONObject> generalD = getGeneral(receiver, MessageType.D);FutureTask<JSONObject> generalE = getGeneral(receiver, MessageType.E);//对五个异步对象进行执行executorService.execute(generalA);executorService.execute(generalB);executorService.execute(generalC);executorService.execute(generalD);executorService.execute(generalE);//获取到五个对应的异步结果,时间取决于最慢的一个异步方法try { response.put("a_result", generalA.get()); response.put("b_result", generalB.get()); response.put("c_result", generalC.get()); response.put("d_result", generalD.get()); response.put("e_result", generalE.get()); return response;} catch (InterruptedException e) { e.printStackTrace();} catch (ExecutionException e) { e.printStackTrace();} finally { //在所有结束情形下关闭线程池,回收资源 executorService.shutdown();} |
下面是getGeneral
的代码:
123456789 |
private FutureTask<JSONObject> (String receiver, MessageType messageType) { return new FutureTask<JSONObject>(new Callable<JSONObject>() { public JSONObject call() throws Exception { //Do Something .... return messageJson; } });} |
这样就完成了我们的五组异步调用.
异步方面我暂且也学到这里,将来有机会继续更新有关异步的内容.