记录一下采用java来实现异步的事件驱动模型

1. node.js中基本上都是采用异步的事件驱动模型来实现的,如何采用Java代码实现一个异步的事件驱动模型呢?下面的例子的场景是模拟借阅者向图书管理员借书。 

/**
 * 图书借阅者
 * <p>
 * 图书借阅者的行为便是借书,其中需要与图书管理员交互
 * 所以需要持有管理员的引用
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Person {

    String username;

    Integer age;

    LibraryAdmin admin;

    public void doSomething() {
        IntStream.rangeClosed(1, 10).forEach(i -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("开始去做其他事情" + i);
        });
    }

    /**
     * 联系图书管理员
     */
    public void connect(LibraryAdmin admin) {
        this.admin = admin;
    }

    /**
     * 借阅书籍
     */
    public void borrowBooks(String bookName) {
        System.out.println(username + ":我想借一本书, 名为:" + bookName);
        ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1));
        pool.execute(() -> {
            // 小明向管理员发送请求
            admin.receiveRequest(username, bookName, (error, callback) -> {
                while (Objects.isNull(callback) && Objects.isNull(error)) {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                if (Objects.nonNull(error)) {
                    System.out.println("error = " + error);
                } else {
                    System.out.println("成功借阅到书籍");
                    System.out.println("callback = " + callback);
                }
            });
        });
        // 小明开始去做其他事情
        doSomething();
        pool.shutdown();
    }
}
/**
 * 定义一个图书管理员
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
@Data
public class LibraryAdmin {

    BookFactory bookFactory;


    /**
     * 1.接收借阅者请求
     * 2.管理员查找借阅者需要的书籍
     * 3.通知借阅者图书已找到
     *
     * @return
     */
    public void receiveRequest(String username, String bookName, EventCallback<Book> callback) {
        Book book = bookFactory.getByName(bookName);
        if (Objects.nonNull(book)) {
            book.setBorrowStartDate(LocalDateTime.now());
            book.setBorrowEndDate(LocalDateTime.now().plusDays(100));
            book.setUsername(username);
            callback.event(null, new Callback<>(book));
        } else {
            callback.event(new Error(500, "未查询到指定的书籍"), null);
        }
    }
}
/**
 * 事件回调接口
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
public interface EventCallback<T> {

    void event(Error error, Callback<T> callback);
}
/**
 * 异常错误通知类
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Error {

    Integer status;

    String errorMsg;

    public Error() {
    }

    public Error(Integer status, String errorMsg) {
        this.status = status;
        this.errorMsg = errorMsg;
    }
}
/**
 * 回调类
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Callback<T> {

    T data;

    public Callback() {
    }

    public Callback(T data) {
        this.data = data;
    }
}
/**
 * 图书类
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
@Data
@FieldDefaults(level = AccessLevel.PRIVATE)
public class Book {

    /**
     * 书名
     */
    String bookName;

    /**
     * 借阅开始时间
     */
    LocalDateTime borrowStartDate;

    /**
     * 借阅结束时间
     */
    LocalDateTime borrowEndDate;

    /**
     * 借阅人
     */
    String username;

    public Book() {
    }

    public Book(String bookName) {
        this.bookName = bookName;
    }
}
/**
 * 图书工厂,通过选择指定的书名,来生成对应的书籍
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
public class BookFactory {


    /**
     * 返回图书
     *
     * @author xiaofeifei
     * @date 2020-02-13
     * @updateDate 2020-02-13
     * @updatedBy xiaofeifei
     * @param
     * @return
     */
    public Book getByName(String bookName) {
        try {
            // 随机睡10秒
            TimeUnit.SECONDS.sleep(new Random().nextInt(10));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new Book(bookName);
    }

}
/**
 * 业务逻辑处理类
 *
 * 用户向图书管理员借阅书籍,用户是主动方,首先要与管理员进行交互
 *
 * @author xiaofeifei
 * @date 2020-02-13
 * @since
 */
public class BusinessLogicHandler {

    public static void main(String[] args) {
        BookFactory bookFactory = new BookFactory();
        LibraryAdmin admin = new LibraryAdmin();
        admin.setBookFactory(bookFactory);
        Person person = new Person();
        person.setUsername("小明");
        // 与图书管理员取得联系
        person.connect(admin);
        // 开始借书
        person.borrowBooks("事件驱动模型");
    }
}

运行结果如下:

这样,我们就实现了一个异步的事件驱动模型啦。

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页