Gahing's blog Gahing's blog
首页
知识体系
  • 前端基础
  • 应用框架
  • 工程能力
  • 应用基础
  • 专业领域
  • 业务场景
  • 前端晋升 (opens new window)
  • Git
  • 网络基础
  • 算法
  • 数据结构
  • 编程范式
  • 编解码
  • Linux
  • AIGC
  • 其他领域

    • 客户端
    • 服务端
    • 产品设计
软素质
  • 面试经验
  • 人生总结
  • 个人简历
  • 知识卡片
  • 灵感记录
  • 实用技巧
  • 知识科普
  • 友情链接
  • 美食推荐 (opens new window)
  • 收藏夹

    • 优质前端信息源 (opens new window)
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Gahing / francecil

To be best
首页
知识体系
  • 前端基础
  • 应用框架
  • 工程能力
  • 应用基础
  • 专业领域
  • 业务场景
  • 前端晋升 (opens new window)
  • Git
  • 网络基础
  • 算法
  • 数据结构
  • 编程范式
  • 编解码
  • Linux
  • AIGC
  • 其他领域

    • 客户端
    • 服务端
    • 产品设计
软素质
  • 面试经验
  • 人生总结
  • 个人简历
  • 知识卡片
  • 灵感记录
  • 实用技巧
  • 知识科普
  • 友情链接
  • 美食推荐 (opens new window)
  • 收藏夹

    • 优质前端信息源 (opens new window)
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 中间件

  • 云原生

  • 分布式

  • 存储技术

  • 数据库

  • 服务部署

  • 编程语言

    • Go

    • Java

      • Android Binder学习笔记
      • BigInteger源码解析
      • CountDownLatch使用之统计任务花费时间
      • Integer 源码方法学习
      • Java Executors 学习笔记
        • 创建ThreadPoolExecutor
        • 返回结果
        • 运行多个任务并处理第一个结果
        • 运行多个任务并处理所有结果
        • 延迟运行任务ScheduledThreadPoolExecutor
        • 执行周期性任务
        • 取消任务
      • Java IO
      • Java NIO
      • NDK-JNI开发笔记
      • OpenGL ES 开发笔记
      • ThreadLocal
      • 「Java并发编程」读书笔记
      • 「垃圾收集」学习笔记
      • 动手写一个并发缓存框架 历程
  • 计算技术

  • 服务端
  • 编程语言
  • Java
gahing
2020-06-29
目录

Java Executors 学习笔记草稿

# 创建ThreadPoolExecutor

  • ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
    • 为每个接收到的任务创建一个线程(如果池中没有空闲的线程)
    • 提交大量的任务,并且它们有很长的(执行)时间,会使系统过载和引发应用程序性能不佳的问题
  • ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(5);
    • 创建固定大小例如5的ThreadPoolExecutor
    • 提交超过最大线程数的任务,剩下的任务将会被阻塞,直到有空闲的线程来处理它们

# 返回结果

  • executor.submit(Runnable()) 无返回结果
  • Future<?> result=executor.submit(Callable<?>) 返回Future对象来管理任务
    • result.isDone():所管理任务是否完成
    • resultList.add(result),利用while (executor.getCompletedTaskCount()<resultList.size());让所有管理任务的Future执行完
    • result.get()获得任务结束返回的对象

# 运行多个任务并处理第一个结果

利用ThreadPoolExecutor类提供的invokeAny(Collection tasks)方法(接受的是Callable任务),输入参数为一个任务队列,ThreadPoolExecutorc处理所有的任务,返回最早执行完任务的一个结果

# 运行多个任务并处理所有结果

上面利用while (executor.getCompletedTaskCount()<resultList.size());让管理任务的Future执行完,其实可以使用 executor.invokeAll(Collection tasks)去执行任务列表,并且返回List<Future<Result>> resultList,此时主线程等待invokeAll执行完后(类似上面的while)进行下一步

# 延迟运行任务ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor executor=(ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(int corePoolSize);
executor.schedule(Callable callable,Long delay(任务在执行前等待多长时间), TimeUnit 时间单位如TimeUnit.SECONDS);
//使用executor的awaitTermination()方法,等待所有任务完成。
//注:这里调用ScheduledThreadPoolExecutor的shutdown()方法,默认不会结束未执行的任务(等待delay执行的task)
//可以通过ScheduledThreadPoolExecutor类的setExecuteExistingDelayedTasksAfterShutdownPolicy()方法来改变这种行为,
//设为false就与其他Executor类一样了

# 执行周期性任务

之前创建的executor,任务在执行完就被executor删除了,需要重新执行时需要再向executor提交任务 可以通过:

ScheduledExecutorService executor=Executors.newScheduledThreadPool(1);
ScheduledFuture<?> result=executor.scheduleAtFixedRate(Runnable command,long initialDelay, long period, TimeUnit.SECONDS); 
 或者 executor.scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
//注1:如果用的是scheduleAtFixedRate 周期运行,你有一个花5s执行的周期性任务,而period是3s,那么会在运行5s的任务后再运行5s周期任务,不会出现2个任务同时运行。而如果是scheduleWithFixedDelay 会运行完5s的任务后过3s再运行
//result.getDelay(TimeUnit.MILLISECONDS));获取下次任务执行的剩余时间
//注2:此executor.shutdown()方法默认的行为是,当你调用这个方法时,计划任务就结束。 你可以使用ScheduledThreadPoolExecutor类的 setContinueExistingPeriodicTasksAfterShutdownPolicy()方法设置true值改变这个行为。在调用 shutdown()方法时,周期性任务将不会结束。

# 取消任务

Future<?> result=executor.submit(task);
result.cancel(boolean mayInterruptIfRunning);
System.out.printf("Main: Canceled: %s\n",result.isCanceled());
//在cacle方法执行后,  isDone will always return true
System.out.printf("Main: Done: %s\n",result.isDone()); 

cancel方法详解:

if(该task已经完成||之前已被取消||由于其他原因不能取消)return false;
else if(该task正在等待executor获取执行它的线程)then 那么task取消,return true;
else if(这个任务已经正在运行){
    if(mayInterruptIfRunning){任务取消,return true;}
    else 任务不取消,return false;
}

注:Future.cancel()方法,其实是发送一个中断请求,线程是否执行中断,jvm需要得到检测中断的时间片(Thread.sleep) 或 **Thread.interrupted()**的判断 见http://ifeve.com/thread-executors-9/ (opens new window) 评论

编辑 (opens new window)
上次更新: 2025/06/11, 23:06:59
Integer 源码方法学习
Java IO

← Integer 源码方法学习 Java IO→

最近更新
01
我的 2024 总结
12-31
02
浅谈代码质量与量化指标
08-27
03
快速理解 JS 装饰器
08-26
更多文章>
Theme by Vdoing | Copyright © 2016-2025 Gahing | 闽ICP备19024221号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式