在第1篇中“并发框架基本示例”,提到了Executors和ThreadPool。
其中,还有个“定时调度”的方法,Executors.newScheduledThreadPool(10)。

// 可执行调度命令(定时+周期性)的线程池,拥有固定的线程数// 重复执行,无穷尽public static void scheduledThreadPool() {int initialDelay = 10;int period = 10;Executor executor = Executors.newScheduledThreadPool(10);ScheduledExecutorService scheduler = (ScheduledExecutorService) executor;scheduler.scheduleAtFixedRate(task, initialDelay, period,TimeUnit.SECONDS);}

这段代码,会一直重复执行,是一种常见的场景。

但是,想到一种“只调度N次”的需求,看了下API,没有提供。
就网上搜索“Java 取消线程调度”,找到了1个问答,就研究了下。
代码示例的关键是,使用了线程安全的AtomicInteger和通用同步工具CountDownLatch。

核心逻辑就是,当超过了最大任务数N的时候,取消Future中的任务,countDownLatch中的计数器-1,变为0,“countDownLatch.await()”线程阻塞结束
countDownLatch.countDown();
关于CountDownLatch的进一步介绍,请参考第4篇。

package cn.fansunion.executorframework;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;//有条件地,取消调度
public class ConditionCancelSchedulerDemo {public static Runnable task = new Runnable() {@Overridepublic void run() {System.out.println("Execute a task");}};// 可执行调度命令(定时+周期性)的线程池,拥有固定的线程数// 重复执行,无穷尽public static void scheduledThreadPool() {int initialDelay = 10;int period = 10;Executor executor = Executors.newScheduledThreadPool(10);ScheduledExecutorService scheduler = (ScheduledExecutorService) executor;scheduler.scheduleAtFixedRate(task, initialDelay, period,TimeUnit.SECONDS);}public static void main(String[] args) throws Exception {scheduledThreadPool();conditionCancelScheduler();}private static void conditionCancelScheduler() throws InterruptedException {final String jobID = "my_job_1";final AtomicInteger count = new AtomicInteger(0);final Map<String, Future> futures = new HashMap<>();// 最多执行10个任务final int maxTaskSize = 10;// CountDownLatch的更多用法,请参考CountDownLatchDemofinal CountDownLatch countDownLatch = new CountDownLatch(1);ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();Future future = scheduler.scheduleWithFixedDelay(new Runnable() {@Overridepublic void run() {System.out.println(count.getAndIncrement());// 当调度执行,第maxTaskSize+1个任务的时候,取消Future中的任务。第11个任务if (count.get() > maxTaskSize) {System.out.println("a");Future f = futures.get(jobID);if (f != null) {f.cancel(true);}// countDownLatch中的计数器-1,变为0// “countDownLatch.await()”线程阻塞结束countDownLatch.countDown();}}}, 0, 1, TimeUnit.SECONDS);futures.put(jobID, future);countDownLatch.await();scheduler.shutdown();}
}

更多代码示例:
http://git.oschina.net/fansunion/Concurrent(逐步更新中)

参考资料:
java并发编程-Executor框架
http://www.iteye.com/topic/366591

有条件地终止 ScheduledExecutorService 中运行的定时任务
http://www.oschina.net/question/1158769_119659?sort=time

JDK API 文档

转载于:https://www.cnblogs.com/qitian1/p/6462508.html

Java并发和多线程3:线程调度和有条件取消调度相关推荐

  1. JAVA并发与多线程相关面试题总结

    JAVA并发与多线程相关面试题总结 1.什么是进程.线程.协程,它们之间的关系是怎样的? 进程: 本质上是一个独立执行的程序,是计算机中的程序关于数据集合上的一次运行活动,进程是操作系统进行资源分配和 ...

  2. Java并发编程-多线程基础

    Java多线程基础 1.多线程概述 实现线程的两种方式 继承Thread类 实现Runnable接口 2.线程生命周期 获取线程的名字和线程对象 3.线程的休眠 sleep方法 终止线程的休眠 强行终 ...

  3. java并发编程-进程和线程调度基础

      弄清楚计算机底层进程.线程调度等原理对我们理解java并发编程有很大的帮助. 文章目录 1.什么是进程 2.什么是线程 3.进程和线程的区别与联系 4.CPU内核数和线程数的关系 5.CPU时间片 ...

  4. Java并发与多线程

    1.多线程优点 资源利用率更好:文件读写操作 程序设计在某些情况下更简单: 程序响应更快:端口监听操作 2.多线程的代价 设计更复杂:多线程共享数据时尤其需要注意 上下文切换的开销: CPU 会在一个 ...

  5. 100道Java并发和多线程面试题

    1.多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了,还管它有什么用?在我看来,这个回答更扯淡.所谓"知其然知其所以然","会用"只是 ...

  6. java 并发编程多线程_多线程(一)java并发编程基础知识

    线程的应用 如何应用多线程 在 Java 中,有多种方式来实现多线程.继承 Thread 类.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现带 ...

  7. JAVA并发编程——多线程

    目录 线程的特点 轻型实体 独立调度和分配的基本单位 可并发执行 共享进程资源 线程的实现 使用内核线程实现 使用用户线程实现 使用用户线程加轻量级线程混合实现 Java线程实现 每日寄语 线程的特点 ...

  8. java并发编程:多线程基础

    文章目录 并发编程三要素 并发编程内存模型 多线程 创建线程的三种方式 volatile synchronized 线程池 ThreadPoolExcutor![在这里插入图片描述](https:// ...

  9. Java并发编程(多线程)中的相关概念

    众所周知,在Java的知识体系中,并发编程是非常重要的一环,也是面试中必问的题,一个好的Java程序员是必须对并发编程这块有所了解的. 并发必须知道的概念 在深入学习并发编程之前,我们需要了解几个基本 ...

最新文章

  1. 深度学习综述(LeCun、Bengio和Hinton)
  2. JDBC中Statement与PreparedStatement的区别
  3. python输入语句是什么意思_Python输入/输出语句
  4. 是什么影响了数据库索引选型?
  5. Stanford Local Programming Contest 2011
  6. golang | 空结构体struct{}的用法
  7. 如何在ADO中使用数据读取器(DataReader)读取数据
  8. PQ分区工具超详细图文教程
  9. 机器学习——k邻近算法(kNN)
  10. 大数据杀熟?我从银行数仓项目学到了什么
  11. Android-系统服务-ClipboardManager
  12. 深圳的住房公积金的那些事儿~(缴纳标准,用处用法)
  13. 虎牙直播电脑配置推荐2021 虎牙直播电脑配置清单
  14. C++ Lua库 源码编译及使用(VS2019)
  15. Mq的幂等性问题分析和基本处理
  16. 吻过你这三个地方的男人,定是对你动了真情,错不了
  17. HCNA-Telnet
  18. 阿里云-DataWorks- ODPS SQL开发
  19. 新浪博客大赛:你刷我也刷?
  20. FreeSwitcch(java使用)

热门文章

  1. AtCoder Beginner Contest 185
  2. 奥维地图导入西安坐标_带了坐标的照片,要上天了
  3. java 压缩 空目录_java zip压缩与解压-支持空目录,保留文件修改时间
  4. 游戏服务器停机维护,游戏是如何做到服务器不停机维护的?
  5. 单点登录有关跨域的点
  6. Java发送邮箱验证码、session校验功能
  7. 凉凉了,Eureka 宣布闭源,Spring Cloud 何去何从? 1
  8. XML文档中的xmlns、xmlns:xsi和xsi:schemaLocation
  9. JDBC-简单连接Oracle Database
  10. Linux Shell常用命令学习(1)