Java回调接口设计&&Lambda改造
设计之初
作为一名有技术情怀的程序员,在日常开发中,我们会遇到多种多样的场景,比如说在代码执行完成后进行的同步操作,亦或者是在代码执行过程中发生的异步操作,如果实现接口设计呢?老规矩,查资料,翻代码,找实现的API,而后进行扩展,做到举一反三。
Java对同步回调实现的支持
// 答案一:
// 顺序执行代码,实现不同方法的顺序压栈,通过利用java虚拟机栈的特性,实现代码顺序执行,而后执行回调函数
// 伪代码实现
public class TestByOrder{
public static void main(String[] args) throws ExecutionException, InterruptedException {
method1(); // 栈帧
method2(); // 栈帧
callBackMethod(); // 栈帧
}
public void method1(){
...
}
public void method2(){
...
}
}
// 答案二:
// 在java并发包中,可使用 java.util.concurrent.Future#get() 实现回调,使用 Executors#newSingleThreadExecutor()和ExecutorService#submit()实现同步
// 代码实现
public class TestFuture{
public static void main(String[] args) throws ExecutionException, InterruptedException {
// future 实现同步回调
futures();
}
private static void futures() throws ExecutionException, InterruptedException {
ExecutorService executorService =
Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(() -> {
return "hello world future";
});
System.out.println(future.get());
executorService.shutdown();
System.out.println("future 同步回调...");
}
Java对异步回调实现的支持
// 答案一:
// 通过新起线程的方式实现异步处理,new Thread()#run,实现Runnable接口都可以
// 代码实现
public class TestRunnable{
public static void main(String[] args) throws ExecutionException, InterruptedException {
// runnable 实现异步回调
runnable();
}
private static void runnable() throws InterruptedException {
new Thread(() -> System.out.println("hello world runnable 1")).start();
new Thread(() -> {
try {
// 执行 RPC 或者 查询 DB 耗时操作
TimeUnit.SECONDS.sleep(1);
System.out.println("hello world runnable 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("runnable 异步回调...");
}
}
// 答案二:
// 通过java并发包中Executor#execute,实现异步执行
// 代码实现
public class TestExecute(){
public static void main(String[] args) throws ExecutionException, InterruptedException {
// async 实现异步回调
async();
}
private static void async() {
ExecutorService executorService =
Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
@Override
public void run() {
System.out.println("Hello World async 1");
}
});
executorService.execute(() ->{
System.out.println("Hello World async 2");
});
// executorService.execute(() ->{
// throw new RuntimeException("手动抛出的异常...");
// });
System.out.println("async 异步回调...");
executorService.shutdown();
}
}
自定义实现函数式回调接口
// 函数式回调接口设计
public class CallbackDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 同步执行
sync();
}
private static void sync() {
CallbackExecutor callbackExecutor = new CallbackExecutor();
Optional.ofNullable(callbackExecutor).get().execute(() -> System.out.println("自定义执行器..."));
callbackExecutor.execute(() -> {
System.out.println("hello world sync 1");
});
callbackExecutor.execute(() -> {
System.out.println("hello world sync 2");
});
callbackExecutor.run();
System.out.println("sync 同步回调...");
}
public interface Callback {
void callback();
}
public static class CallbackExecutor{
private Queue<Callback> callbackQueue = new LinkedList<>();
public void execute(Callback callback) {
callbackQueue.add(callback);
}
public void run() {
callbackQueue.forEach(callback -> callback.callback());
}
}
}
Lambda方式改造函数式回调接口
// 上述实现了函数式回调接口
// 由于项目采用的是JDK1.8.0_92,为了适应代码流式化和代码简洁处理、代码公共逻辑抽取,故此进行改造
/**
* @ClassName: Java8CallbackDemo
* @Description: java 8 Lambda 实现 CallbackDemo
* @Author: 尚先生
* @CreateDate: 2019/5/8 9:54
* @Version: 1.0
*/
public class Java8CallbackDemo {
// 定义全局并发安全队列
public static LinkedBlockingQueue<Callback> queues = new LinkedBlockingQueue<>();
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 同步执行
sync();
}
private static void sync() {
// 初始化 InvokerHandler 对象
InvokerHandler invokerHandler = new InvokerHandler();
invokerHandler.execute((Java8CallbackDemo.Callback)() -> {
System.out.println("hello world sync 1");},(function -> queues.add(function)));
invokerHandler.execute((Java8CallbackDemo.Callback)() -> {
System.out.println("hello world sync 2");},(function -> queues.add(function)));
queues.forEach(queue -> invokerHandler.run(queue,Callback::callback));
System.out.println("sync 同步回调...");
}
interface Callback {
void callback();
}
static class InvokerHandler {
public <T, R> R execute(T t, Function<T, R> function) {
return function.apply(t);
}
public <T> void run(T t, Consumer<T> consumer) {
consumer.accept(t);
}
}
}
至此,函数式回调接口设计全部完成,后续章节会讨论更多的模式设计,敬请关注。
完整代码和相关依赖请见GitHub
https://github.com/dwyanewede/project-learn/tree/master/src/main/java/com/learn/demo/design/pattern