概述
有时候我们执行一个任务需要很长时间,单线程环境下 会处于阻塞状态,严重影响效率,那么可以使用一种非阻塞的处理方式,这就是使用多线程。
多线程情况下,问题出来了,我们不知道线程什么时候执行完毕,或者不知道如何处理子线程的结果,那么就有以下两种方式:异步回调和同步等待线程处理结果两种方式
1. 异步回调
直接上代码,固定格式:主业务代码和一个处理结果的接口
/**
* Callback
* 回调一般是异步处理的一种技术。
* 一个回调是被传递到并且执行完该方法。 这种方式只能异步回调,
* 如果需要同步等待线程处理结果可以使用下面介绍的Futures
*/
interface MyCallback {
void doCallback(Map<String, Object> params);
}
public class TestAsyncCallBack {
static ExecutorService es = Executors.newFixedThreadPool(2);
public static void doSomething(MyCallback callback) {
// 初始化一个线程
Thread t = new Thread() {
public void run() {
// 这里是业务逻辑处理
System.out.println("子线任务开始执行:" + Thread.currentThread().getId());
// 为了能看出效果 ,让当前线程阻塞5秒
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("子线任务结束执行:");
// 处理完业务逻辑,
Map<String, Object> params = new HashMap<String, Object>();
params.put("a1", "子线程处理结果");
callback.doCallback(params);
}
};
es.execute(t);
//一定要调用这个方法,不然executorService.isTerminated()永远不为true
es.shutdown();
}
public static void main(String[] args) {
// 内部类 等价于 new MyCallBack(){...}, 主要作用就是重写doCallback方法
doSomething((params) -> {
System.out.println("单个线程也已经处理完毕了,返回参数a1=" + params.get("a1"));
});
System.out.println("主线任务已经执行完了:" + Thread.currentThread().getId());
}
}
2. 使用Future同步等待执行结果
主要是利用了Callable接口开启进行多线程,call方法可以返回结果
/**
* Futures是一个抽象的概念,它表示一个值,该值可能在某一点变得可用。一个Future要么获得计算完的结果,要么获得计算失败后的异常
* 每传递一个Runnable对象到ExecutorService.submit()方法就会得到一个回调的Future,你能使用它检测是否执行,这种方法可以是同步等待线处理结果
*/
public class TestFuture {
public static void main(String[] args) {
Callable<Result> callable = new Callable<Result>() {
@Override
public Result call() throws Exception {
//这里是业务逻辑处理
//让当前线程阻塞1秒看下效果
Thread.sleep(5000);
return new Result("张三");
}
};
ExecutorService executorService = Executors.newFixedThreadPool(5);
Future<Result> resultFuture = executorService.submit(callable);
executorService.shutdown();
/**
* 无限循环等待任务处理完毕
如果已经处理完毕 isDone返回true
*/
while (!resultFuture.isDone()) {
try {
Result result = resultFuture.get(); // 在这一步阻塞知直到得到子线程返回结果
System.out.println(result.getName());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
class Result {
private String name;
public Result(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
最后
以上就是现代小刺猬为你收集整理的01 Java中的异步回调1. 异步回调2. 使用Future同步等待执行结果的全部内容,希望文章能够帮你解决01 Java中的异步回调1. 异步回调2. 使用Future同步等待执行结果所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复