Java回调接口设计&&Lambda改造

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

公众号推荐

在这里插入图片描述

你可能感兴趣的:(java)