在第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. YII实现dropDownList 联动事件

    因功能需求,需要用到联动,特此记录分享 一.视图中 <div class="main-form"> <?php $form = ActiveForm::begin ...

  2. qt4.7.0 交叉编译环境搭建经验总结

    一.前期软件准备: 1 .虚拟机fedora9.到fedora官网下载,地址 http://fedoraproject.org/   版本推荐使用fedora9,在vm内安装,并且不安装vmware ...

  3. vue使用SockJS实现webSocket通信

    以前使用websocket都是使用 window.webSocket = new WebSocket('ws://' + config.webSocketUrl + '/webData/websock ...

  4. ssm整合shiro—实现认证和授权

    1.简述 1.1    Apache Shiro是Java的一个安全框架.是一个相对简单的框架,主要功能有认证.授权.加密.会话管理.与Web集成.缓存等. 1.2   Shiro不会去维护用户.维护 ...

  5. Java Pattern Matcher 正则表达式需要转义的字符

    见:http://blog.csdn.net/bbirdsky/article/details/45368709 /** * 转义正则特殊字符 ($()*+.[]?\^{},|) * * @param ...

  6. Swift入门(四)——可选类型(Optionals)与断言(Assert)

    可选类型是什么? 首先看一个问题,Swift中String类型的变量有一个叫做toInt的方法,能够把String类型变量转换为Int类型变量. var stringValue = "5&q ...

  7. 每天一个JavaScript实例-tab标签切换

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. Android自己定义控件系列三:自己定义开关button(二)

    接上一篇自己定义开关button(一)的内容继续.上一次实现了一个开关button的基本功能.即自己定义了一个控件.开关button,实现了点击切换开关状态的功能.今天我们想在此基础之上.进一步实现触 ...

  9. 杂项-编程:AOP(面向切面编程)

    ylbtech-杂项-编程:AOP(面向切面编程) 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一 ...

  10. 杂项-Java:Spring Cloud

    ylbtech-杂项-Java:Spring Cloud Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册. ...