在第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() {
@Override
public 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的更多用法,请参考CountDownLatchDemo
final CountDownLatch countDownLatch = new CountDownLatch(1);
ScheduledExecutorService scheduler = Executors
.newSingleThreadScheduledExecutor(); Future future = scheduler.scheduleWithFixedDelay(new Runnable() {
@Override
public 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 文档

Java并发和多线程3:线程调度和有条件取消调度的更多相关文章

  1. Java并发和多线程2:3种方式实现数组求和

    本篇演示3个数组求和的例子. 例子1:单线程例子2:多线程,同步求和(如果没有计算完成,会阻塞)例子3:多线程,异步求和(先累加已经完成的计算结果) 例子1-代码 package cn.fansuni ...

  2. Java并发与多线程教程(2)

    Java同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) ...

  3. java并发与多线程面试题与问题集合

    http://www.importnew.com/12773.html     https://blog.csdn.net/u011163372/article/details/73995897    ...

  4. Java并发和多线程(一)基础知识

    1.java线程状态 Java中的线程可以处于下列状态之一: NEW: 至今尚未启动的线程处于这种状态. RUNNABLE: 正在 Java 虚拟机中执行的线程处于这种状态. BLOCKED: 受阻塞 ...

  5. Java 并发和多线程(一) Java并发性和多线程介绍[转]

    作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...

  6. Java并发和多线程:序

      近期,和不少公司的"大牛"聊了聊,当中非常多是关于"并发和多线程"."系统架构"."分布式"等方面内容的.不少问题, ...

  7. Java并发与多线程教程(1)

    Java并发性与多线程介绍 在过去单CPU时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务 ...

  8. Java并发和多线程1:并发框架基本示例

    Executor框架是指java 5中引入的一系列并发库中与executor相关的一些功能类,其中包括ThreadPool,Executor,Executors,ExecutorService,Com ...

  9. Java并发基础--多线程基础

    一.多线程基础知识 1.进程和线程 进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程:进程也是程序的一次执行过程,是系统运行程序的基本单位:系统运行 ...

随机推荐

  1. Python JSON - 世界人口图

    世界人口图 从https://datahub.io/网站搜索population,下载世界人口json数据. from pygal.maps.world import COUNTRIES def ge ...

  2. 使用magento eav数据模型为用户提供图片上传功能的实践

    一,在megento表中,增加一个存储上传图片路径的属性, 给magento的customer实体类型增加一个audit_file_path属性,因为要customer使用的是EAV模型,得操作几个关 ...

  3. NEFU 2

    其实就是筛选素数. 如,若能被2是质数,则2的倍数全是合数.如此循环. #include <iostream> #include <math.h> #include <c ...

  4. python的urlencode与urldecode

    ```python3.x中urlencode在urllib.parse模块中``` 当url地址含有中文,或者参数有中文的时候,这个算是很正常了,但是把这样的url作为参数传递的时候(最常见的call ...

  5. [HTML5] Accessibility Implementation for complex component

    When you developing a complex component by your own, one thing you cannot ignore is Accessibility. C ...

  6. TeamTalk Android代码分析(业务流程篇)

    TeamTalk Android代码分析(业务流程篇) 1.1 总体结构 1.总体结构有点类似MVC的感觉,模块结构从上向下大体是: UI层:Activity和Fragment构成,期间包括常用的一些 ...

  7. How to improve Java&#39;s I/O performance( 提升 java i/o 性能)

    原文:http://www.javaworld.com/article/2077523/build-ci-sdlc/java-tip-26--how-to-improve-java-s-i-o-per ...

  8. ZooKeeper分布式集群部署及问题

    ZooKeeper为分布式应用系统提供了高性能服务,在许多常见的集群服务中被广泛使用,最常见的当属HBase集群了,其他的还有Solr集群.Hadoop-2中的HA自己主动故障转移等. 本文主要介绍了 ...

  9. 【DataStructure】The difference among methods addAll(),retainAll() and removeAll()

    In the Java collection framework, there are three similar methods, addAll(),retainAll() and removeAl ...

  10. js 回调函数小例子

    js 回调函数小例子 <script> //将函数作为另一个函数的参数 function test1(){ alert("我是test1"); } function t ...