长沙java培训
达内长沙芙蓉路中心

18487146383

热门课程

长沙Java培训机构java的异步结果

  • 时间:2017-02-27
  • 发布:长沙Java培训
  • 来源:达内新闻

长沙Java培训机构的小编这一期给大家分享异步结果。

在主从模式中,手工创建线程往往比较麻烦,一种常见的模式是异步调用,异步调用返回一个一般称为Promise或Future的对象,通过它可以获得最终的结果。在Java中,表示子任务的接口是Callable,声明为:

public interface Callable<V> {

V call() throws Exception;

}

为表示异步调用的结果,我们定义一个接口MyFuture,如下所示:

public interface MyFuture <V> {

V get() throws Exception ;

}

这个接口的get方法返回真正的结果,如果结果还没有计算完成,get会阻塞直到计算完成,如果调用过程发生异常,则get方法抛出调用过程中的异常。

为方便主线程调用子任务,我们定义一个类MyExecutor,其中定义一个public方法execute,表示执行子任务并返回异步结果,声明如下:

public <V> MyFuture<V> execute(final Callable<V> task)

利用该方法,对于主线程,它就不需要创建并管理子线程了,并且可以方便地获取异步调用的结果,比如,在主线程中,可以类似这样启动异步调用并获取结果:

public static void main(String[] args) {

MyExecutor executor = new MyExecutor();

//子任务

Callable<Integer> subTask = new Callable<Integer>() {

@Override

public Integer call() throws Exception {

// ...执行异步任务

int millis = (int) (Math.random() * 1000);

Thread.sleep(millis);

return millis;

}

};

//异步调用,返回一个MyFuture对象

MyFuture<Integer> future = executor.execute(subTask);

// ...执行其他操作

try {

//获取异步调用的结果

Integer result = future.get();

System.out.println(result);

} catch (Exception e) {

e.printStackTrace();

}

}

MyExecutor的execute方法是怎么实现的呢?它封装了创建子线程,同步获取结果的过程,它会创建一个执行子线程,该子线程的代码如下所示:

static class ExecuteThread<V> extends Thread {

private V result = null;

private Exception exception = null;

private boolean done = false;

private Callable<V> task;

private Object lock;

public ExecuteThread(Callable<V> task, Object lock) {

this.task = task;

this.lock = lock;

}

@Override

public void run() {

try {

result = task.call();

} catch (Exception e) {

exception = e;

} finally {

synchronized (lock) {

done = true;

lock.notifyAll();

}

}

}

public V getResult() {

return result;

}

public boolean isDone() {

return done;

}

public Exception getException() {

return exception;

}

}

这个子线程执行实际的子任务,记录执行结果到result变量、异常到exception变量,执行结束后设置共享状态变量done为true并调用notifyAll以唤醒可能在等待结果的主线程。

MyExecutor的execute的方法的代码为:

public <V> MyFuture<V> execute(final Callable<V> task) {

final Object lock = new Object();

final ExecuteThread<V> thread = new ExecuteThread<>(task, lock);

thread.start();

MyFuture<V> future = new MyFuture<V>() {

@Override

public V get() throws Exception {

synchronized (lock) {

while (!thread.isDone()) {

try {

lock.wait();

} catch (InterruptedException e) {

}

}

if (thread.getException() != ull) {

throw thread.getException();

}

return thread.getResult();

}

}

};

return future;

}

execute启动一个线程,并返回MyFuture对象,MyFuture的get方法会阻塞等待直到线程运行结束。

以上的MyExecutore和MyFuture主要用于演示基本原理,实际上,Java中已经包含了一套完善的框架Executors,相关的部分接口和类有:

表示异步结果的接口Future和实现类FutureTask

用于执行异步任务的接口Executor、以及有更多功能的子接口ExecutorService

用于创建Executor和ExecutorService的工厂方法类Executors

了解详情请登陆长沙达内Java培训官网(cs.Java.tedu.cn)!

上一篇:【长沙达内Java培训】java的集合点
下一篇:如何思考“互联网+”背景下体育信息服务业发展若干问题

长沙java培训机构 程序员为什么睡眠不好?答案在这里!

【长沙Java培训】程序员记住,你写的代码是给人看的?

学编程培训班多少钱?你得看下课程含金量!

学习从构造函数看线程安全!长沙达内java

选择城市和中心
贵州省

广西省

海南省