在第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. sax解析xml文件的DefaultHandler处理类

    一千年的时光,我无数次掀起岁月的帷幔,只为和你,在某一个平静如水的日子相遇,然后相识,倾情一生,缱绻一世,好美的散文,好吧,我情愿把这个“你”当作android:),使用sax解析xml文件是我见到过 ...

  2. tf.truncated_normal和tf.random_normal使用方法的区别

    1.tf.truncated_normal使用方法 tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=No ...

  3. FactoryBean简介

    网上看了很多关于FactoryBean和BeanFactory的介绍,总感觉说的不够简单.直白,今天用自己的语言来描述下,如果有不对的地方,还请大家指正. 1. FactoryBean和BeanFac ...

  4. HDU5924 Mr. Frog’s Problem

    /* HDU5924 Mr. Frog’s Problem http://acm.hdu.edu.cn/showproblem.php?pid=5924 数论 * */ #include <cs ...

  5. Grand Central Dispatch(GCD)详解

    概述 GCD是苹果异步执行任务技术,将应用程序中的线程管理的代码在系统级中实现.开发者只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD就能生成必要的线程并计划执行任务.由于 ...

  6. HDU 2138

    这题用MILLER测试应该是不可避免的. #include <iostream> #include <cstdio> #include <stdlib.h> #in ...

  7. 回想四叉树LOD地形(上)

           唉.~事实上这是在差点儿相同一年前实现的东西,但当时没作好记录.放了那么久了,假设不做点总结的话,好像有点对不起自己,于是·········还是做点什么吧.        我脑洞比較小, ...

  8. 微信小程序怎么获取当前页面的url

    使用getCurrentPages可以获取当前加载中所有的页面对象的一个数组,数组最后一个就是当前页面. var pages = getCurrentPages() //获取加载的页面 var cur ...

  9. 2015.04.29,外语,读书笔记-《Word Power Made Easy》 14 “如何谈论日常现象” SESSION 39

    HOW TO TALK ABOUT COMMON PHENOMENA AND OCCURRENCES TEASER PREVIEW dire(['daiә(r)] adj. 可怕的,悲惨的,灾难警告的 ...

  10. 2015.04.21,外语,读书笔记-《Word Power Made Easy》 11 “如何辱骂敌人” SESSION 31

    1.no reverence iconoclast([ai'kɔnәklæst]  n. 毁坏宗教神像的人, 提倡打破旧习的人)藐视传统.在青年的反叛期很容易出现iconoclasm([ai'kɔnә ...