口碑好网站建设公司,天元建设集团有限公司总工程师,商标注册网官网查询,wordpress循环所有文章耗时的同步请求自动转异步请求问题描述问题处理代码实现问题描述
现在在项目中碰到一个情况#xff0c;导出数据到excel#xff0c;在数据量比较下的时候直接下载#xff0c;在数据量比较大时保存到服务的文件列表#xff0c;后续再供用户下载。 也就是需要避免前端因后端…
耗时的同步请求自动转异步请求问题描述问题处理代码实现问题描述
现在在项目中碰到一个情况导出数据到excel在数据量比较下的时候直接下载在数据量比较大时保存到服务的文件列表后续再供用户下载。 也就是需要避免前端因后端处理时间过长而提示超时的问题。
问题处理
步骤 1、主线程开启线程1进行数据读取和转换byte数组处理结束唤醒主线程 2、开启线程2进行计时到时间后唤醒主线程 3、主线程阻塞等待唤醒 4、判断是被哪个线程唤醒的如果是线程1直接返回数据请求结束如果是线程2则表示读取转换未完成需要转换为异步处理这时直接结束请求返回提示信息。 计划 1、使用包括主线程在内的3个线程 2、使用CountDownLatch进行主线程唤醒
代码实现
伪代码如下
ThreadPoolTaskExecutor executor;byte[] handle() throws InterruptedException, ExecutionException {// 技术器为 1无论哪个线程计数都会唤醒主线程CountDownLatch latch new CountDownLatch(1);// 记录 是否数据处理完成AtomicBoolean flag new AtomicBoolean(false);// 数据读取线程FutureListMapString, Object future executor.submit(() - {synchronized (flag){flag.set(true);latch.countDown();}return readSomething();});executor.execute(() - {try {Thread.sleep(5 * 1000);}catch (Exception ignored){}finally {latch.countDown();}});if (!flag.get()) {latch.await();}if (flag.get()) {// 数据读取完成ListMapString, Object maps future.get();// 返回下载数据return toExcelByte(maps);}else {// 数据读取未完成需要转异步并返回响应executor.execute(() - {ListMapString, Object maps;try {maps future.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();return;}toSaveLocal(toExcelByte(maps));});return 当前数据处理时间较长请稍后在文件列表中下载.getBytes();}}ListMapString, Object readSomething() {return Collections.EMPTY_LIST;
}byte[] toExcelByte(ListMapString, Object maps) {// 数据保存到excel bytereturn new byte[]{};
}void toSaveLocal(byte[] bytes) {// 写到本地服务器或者文件服务器以供下载
}