Java线程之异步回调(Callback)

Java线程之异步回调(Callback)

●介绍 有时候执行一个任务需要很长时间,单线程下线程会处于阻塞状态。这个时候我们会考虑一种非阻塞的处理模式。非阻塞任务在任何编程语言里都必不可少,Java也不例外。多线程就是一个很好的解决办法。 但是多线程是异步处理,异步就意味着不知道处理结果,如果我们需要知道处理结果的时候应该怎么办呢?笔者介绍下面两种方法 ●Callback 回调一般是异步处理的一种技术。一个回调是被传递到并且执行完该方法。这种方式只能异步回调,如果需要同步等待线程处理结果可以使用下面介绍的Futures

package callback;

import java.util.Map;

public interface ICallback {

public void callback(Map params);

}

package callback;

import java.util.HashMap;

import java.util.Map;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

* Callback

* 回调一般是异步处理的一种技术。

* 一个回调是被传递到并且执行完该方法。这种方式只能异步回调,

* 如果需要同步等待线程处理结果可以使用下面介绍的Futures

*/

public class NettyTest1 {

static ExecutorService es = Executors.newFixedThreadPool(2);

public static void doStm(final ICallback callback) {

// 初始化一个线程

Thread t = new Thread() {

public void run() {

// 这里是业务逻辑处理

System.out.println("子线任务执行:"+Thread.currentThread().getId());

// 为了能看出效果 ,让当前线程阻塞5秒

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

// 处理完业务逻辑,

Map params = new HashMap();

params.put("a1", "这是我返回的参数字符串...");

callback.callback(params);

};

};

es.execute(t);

//一定要调用这个方法,不然executorService.isTerminated()永远不为true

es.shutdown();

}

public static void main(String[] args) {

// 内部类 等价于 ICallback callbck = new ICallback的实现类();

// 新手如果对内部类的写法有疑惑可以查看一下编译后的class文件或许能明白

// 在编译的时候会把内部类编译成一个实现了ICallback的class

// doStm(new ICallback() {

// /**

// * 现在这个方法是doStm结束后调用

// * 结束之后会主动把处理参数params传递过来

// */

// @Override

// public void callback(Map params) {

// System.out.println("单个线程也已经处理完毕了,返回参数a1=" + params.get("a1"));

// }

// });

doStm((params)->{

System.out.println("单个线程也已经处理完毕了,返回参数a1=" + params.get("a1"));

});

System.out.println("主线任务已经执行完了:"+Thread.currentThread().getId());

}

}

打印结果:

子线任务执行:11

主线任务已经执行完了:1

单个线程也已经处理完毕了,返回参数a1=这是我返回的参数字符串...

Process finished with exit code 0

Future Futures是一个抽象的概念,它表示一个值,该值可能在某一点变得可用。一个Future要么获得 计算完的结果,要么获得计算失败后的异常。Java在java.util.concurrent包中附带了Future接口,它使用Executor异步执行。例 如下面的代码,每传递一个Runnable对象到ExecutorService.submit()方法就会得到一个回调的Future,你能使用它检测是否执行,这种方法可以是同步等待线处理结果 完成。

package callback;

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

/**

* Future

* Futures是一个抽象的概念,它表示一个值,该值可能在某一点变得可用。一个Future要么获得

计算完的结果,要么获得计算失败后的异常。Java在java.util.concurrent包中附带了Future接口,

它使用Executor异步执行。例

如下面的代码,每传递一个Runnable对象到ExecutorService.submit()方法就会得到一个回调的Future,

你能使用它检测是否执行,这种方法可以是同步等待线处理结果

完成。

*/

public class NettyTest {

public static void main(String[] args) {

//实现一个Callable接口

Callable c = new Callable() {

@Override

public Netty call() throws Exception {

//这里是你的业务逻辑处理

//让当前线程阻塞1秒看下效果

Thread.sleep(1000);

return new Netty("张三");

}

};

ExecutorService es = Executors.newFixedThreadPool(2);

//记得要用submit,执行Callable对象

Future fn = es.submit(c);

//一定要调用这个方法,不然executorService.isTerminated()永远不为true

es.shutdown();

//无限循环等待任务处理完毕 如果已经处理完毕 isDone返回true

while (!fn.isDone()) {

try {

//处理完毕后返回的结果

Netty nt = fn.get();

System.out.println(nt.name);

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

static class Netty {

private String name;

private Netty(String name) {

this.name = name;

}

}

}

打印结果:

张三

Process finished with exit code 0

相关推荐

16 孔 口琴 教學:最完整的入門指南
365bet在线网投

16 孔 口琴 教學:最完整的入門指南

📅 07-08 👁️ 191
word怎么在字下面加点(word里怎么给字加点)
365bet在线网投

word怎么在字下面加点(word里怎么给字加点)

📅 08-12 👁️ 1246
小米3(Mi3/移动3G)
365速发登录入口

小米3(Mi3/移动3G)

📅 07-19 👁️ 8861