Java 并发专题 FutureTask 实现预加载数据 在线看电子书 浏览器浏览网页等

本文主要是介绍Java 并发专题 FutureTask 实现预加载数据 在线看电子书 浏览器浏览网页等,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

继续并发专题~

FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞。

由于:FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞这两个特性,我们可以用来预先加载一些可能用到资源,然后要用的时候,调用get方法获取(如果资源加载完,直接返回;否则继续等待其加载完成)。

下面通过两个例子来介绍下:

1、使用FutureTask来预加载稍后要用的的数据。

package com.zhy.concurrency.futuretask;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/** * 使用FutureTask来提前加载稍后要用到的数据 *  * @author zhy *  */public class PreLoaderUseFutureTask/**  * 创建一个FutureTask用来加载资源  */ private final FutureTask<String> futureTask = new FutureTask<String>(   new Callable<String>()   {    @Override    public String call() throws Exception    {     Thread.sleep(3000);     return "加载资源需要3秒";    }   }); public final Thread thread = new Thread(futureTask); public void start() {  thread.start(); } /**  * 获取资源  *   * @return  * @throws ExecutionException   * @throws InterruptedException   */ public String getRes() throws InterruptedException, ExecutionException {  return futureTask.get();//加载完毕直接返回,否则等待加载完毕 } public static void main(String[] args) throws InterruptedException, ExecutionException {  PreLoaderUseFutureTask task = new PreLoaderUseFutureTask();  /**   * 开启预加载资源   */  task.start();  // 用户在真正需要加载资源前进行了其他操作了2秒  Thread.sleep(2000);  /**   * 获取资源   */  System.out.println(System.currentTimeMillis() + ":开始加载资源");  String res = task.getRes();  System.out.println(res);  System.out.println(System.currentTimeMillis() + ":加载资源结束"); }}

运行结果:

1400902789275:开始加载资源加载资源需要31400902790275:加载资源结束
可以看到,本来加载资源的时间需要3秒,现在只花费了1秒,如果用户其他操作时间更长,则可直接返回,极大增加了用户体验。

2、看下Future的API


可以看到Future的API,还是比简单的,见名知意的感觉,get( long , TimeUnit )还能支持,设置最大等待时间,比如某个操作耗时太长,就可以取消了。

3、FutureTask模拟,用户在线观看电子书的预加载功能

用户观看当前页时,后台预先把下一页加载好,这样可以大幅度提高用户的体验,不需要每一页都等待加载,用户会觉得此电子书软件很流畅,哈哈,用户觉得好,才是真的好。

package com.zhy.concurrency.futuretask;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;/** * 使用FutureTask模拟预加载下一页图书的内容 *  * @author zhy *  */public class BookInstance/**  * 当前的页码  */ private volatile int currentPage = 1/**  * 异步的任务获取当前页的内容  */ FutureTask<String> futureTask = new FutureTask<String>(   new Callable<String>()   {    @Override    public String call() throws Exception    {     return loadDataFromNet();    }   }); /**  * 实例化一本书,并传入当前读到的页码  *   * @param currentPage  */ public BookInstance(int currentPage) {  this.currentPage = currentPage;  /**   * 直接启动线程获取当前页码内容   */  Thread thread = new Thread(futureTask);  thread.start(); } /**  * 获取当前页的内容  *   * @return  * @throws InterruptedException  * @throws ExecutionException  */ public String getCurrentPageContent() throws InterruptedException,   ExecutionException {  String con = futureTask.get();  this.currentPage = currentPage + 1;  Thread thread = new Thread(futureTask = new FutureTask<String>(    new Callable<String>()    {     @Override     public String call() throws Exception     {      return loadDataFromNet();     }    }));  thread.start();  return con; } /**  * 根据页码从网络抓取数据  *   * @return  * @throws InterruptedException  */ private String loadDataFromNet() throws InterruptedException {  Thread.sleep(1000);  return "Page " + this.currentPage + " : the content ...."; } public static void main(String[] args) throws InterruptedException,   ExecutionException {  BookInstance instance = new BookInstance(1);  for (int i = 0; i < 10; i++)  {   long start = System.currentTimeMillis();   String content = instance.getCurrentPageContent();   System.out.println("[1秒阅读时间]read:" + content);   Thread.sleep(1000);   System.out.println(System.currentTimeMillis() - start);  } }}

输出结果:

[1秒阅读时间]read:Page 1 : the content ....2001[1秒阅读时间]read:Page 2 : the content ....1000[1秒阅读时间]read:Page 3 : the content ....1001[1秒阅读时间]read:Page 4 : the content ....1000[1秒阅读时间]read:Page 5 : the content ....1001

可以看到,除了第一次观看当前页需要等待网络加载数据的过程(输出的:2001,1000是加载耗时,1000是用户阅读时间),接下来的页面都是瞬间返回(输出的1000是用户阅读时间),完全不需要等待。

代码都是为了讲解FutureTask的应用场景,,,请勿直接在项目中使用。


好了,就到这里,欢迎各位留言。




           

分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

这篇关于Java 并发专题 FutureTask 实现预加载数据 在线看电子书 浏览器浏览网页等的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/365430

相关文章

使用Python开发一个Ditto剪贴板数据导出工具

《使用Python开发一个Ditto剪贴板数据导出工具》在日常工作中,我们经常需要处理大量的剪贴板数据,下面将介绍如何使用Python的wxPython库开发一个图形化工具,实现从Ditto数据库中读... 目录前言运行结果项目需求分析技术选型核心功能实现1. Ditto数据库结构分析2. 数据库自动定位3

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

pandas数据的合并concat()和merge()方式

《pandas数据的合并concat()和merge()方式》Pandas中concat沿轴合并数据框(行或列),merge基于键连接(内/外/左/右),concat用于纵向或横向拼接,merge用于... 目录concat() 轴向连接合并(1) join='outer',axis=0(2)join='o

批量导入txt数据到的redis过程

《批量导入txt数据到的redis过程》用户通过将Redis命令逐行写入txt文件,利用管道模式运行客户端,成功执行批量删除以Product*匹配的Key操作,提高了数据清理效率... 目录批量导入txt数据到Redisjs把redis命令按一条 一行写到txt中管道命令运行redis客户端成功了批量删除k

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编