ScheduledThreadPoolExecutor周期任务或延时任务线程池

ScheduledThreadPoolExecutor可以代替timer,timer的缺点是一个timer启动一个线程,如果任务在执行时候发生异常,该timer对应的线程会结束

ScheduledThreadPoolExecutor的效率更高,他比timer支持更丰富的功能

public class ScheduledThreadPoolExecutorTest {

    public static void main(String[] args) throws InterruptedException {
        //池中只有一个线程
        ScheduledThreadPoolExecutor schedulePool = new ScheduledThreadPoolExecutor(4);

//      周期任务
//      从上一周期的任务的开始时间到当前周期的任务开始时间的间隔
//      任务的执行时间 > period参数:时间间隔是任务的执行时间。
//      任务的执行时间 < period参数:时间间隔是period参数。
        ScheduledFuture<?> scheduledFuture = schedulePool.scheduleAtFixedRate(new MyRunnable(), 50, 5000, TimeUnit.MILLISECONDS);

//      取消该任务
        Thread.sleep(20000);
        scheduledFuture.cancel(true);

//      延时任务
//      从上一周期的任务的执行结束时间到当前周期的任务开始时间的间隔,固定延迟时间为delay参数,与任务执行时间无关。
//      schedulePool.scheduleWithFixedDelay(new MyRunnable(), 50, 1000, TimeUnit.MILLISECONDS);

    }

    static class MyRunnable implements Runnable {

        int period = 1;

        @Override
        public void run() {
            //为周期任务捕获异常,避免异常影响下一周期的任务执行
            try {
                System.out.println("---------------第 " + period + " 周期-------------");
                System.out.println("begin = " + System.currentTimeMillis() / 1000);//秒
                //任务执行时间
                Thread.sleep(2000);
                System.out.println("end =   " + System.currentTimeMillis() / 1000);
                period++;
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * 计算初始的延迟毫秒数
     * @return
     */
    public    static  long   getDelayMillis(){
        int dayOfHour = 0; // 24h 制
        int minute = 0;
        int second = 0;
        long delay;  //首次执行任务的延迟
        Calendar c = Calendar.getInstance();
        long currentTime = c.getTimeInMillis();
        c.set(Calendar.HOUR_OF_DAY, dayOfHour);
        c.set(Calendar.MINUTE, minute);
        c.set(Calendar.SECOND, second);
        long executeTime = c.getTimeInMillis();
        delay = executeTime - currentTime < 0 ? (executeTime + 24 * 60 * 60 * 1000 - currentTime )
                : (executeTime - currentTime);
        System.out.println("DelayTimeInMillis =" + delay);
        return  delay;
    }
}

原文地址:https://www.cnblogs.com/moris5013/p/11917299.html

时间: 2024-10-14 07:06:59

ScheduledThreadPoolExecutor周期任务或延时任务线程池的相关文章

Java线程池介绍

Java线程池介绍 2015-10-24 ImportNew (点击上方公号,可快速关注) 原文:allegro 译文:ImportNew - paddx 链接:http://www.importnew.com/16845.html 根据摩尔定律(Moore’s law),集成电路晶体管的数量差不多每两年就会翻一倍.但是晶体管数量指数级的增长不一定会导致 CPU 性能的指数级增长.处理器制造商花了很多年来提高时钟频率和指令并行.在新一代的处理器上,单线程程序的执行速率确实有所提高.但是,时钟频率

Java默认提供的线程池

Java的线程池都是通过ThreadPoolExecutor来构建. public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSi

java多线程(三)-Executors实现的几种线程池以及Callable

从java5开始,类库中引入了很多新的管理调度线程的API,最常用的就是Executor(执行器)框架.Executor帮助程序员管理Thread对象,简化了并发编程,它其实就是在 提供了一个中间层,方便程序员管理异步任务的执行,而又不用显式的管理线程的生命周期. Executor采用了线程池实现,也更节约开销,因为是我们启动新线程的首选方法. 示例代码:src/thread_runnable/CachedThreadPool.java 1 public class CachedThreadPo

第8章 线程池的使用

ThreadLocal使每个线程都可以拥有某个变量的一个私有“版本”.然而,只要条件允许,Executor可以自由地重用这些线程.在标准的Executor实现中,当执行需求较低时将回收空闲线程,而当需求增加时将添加新的线程,并且如果从任务中抛出了一个未检查异常,那么将用一个新的工作者线程来替代抛出异常的线程.只有当线程本地值的生命周期受限于任务的生命周期时,在线程池的线程中使用ThreadLocal才有意义,而在线程池的线程中不应该使用ThreadLocal在任务之间传递值. 当有当任务都是同类

JAVA线程池资源回收的问题

最近项目中为了提高用户体验度,前台创建任务后台任务,用多线程来跑. 现在的场景:后台定时任务管理这两个线程池,一个最大线程数10个,一个最大线程数15.应用部署之后,不超过5个小时,服务器负载高,内存使用过多. 分析原因:因为这个功能是excel导入功能,如果前台有大量的导入任务时,那么后台的负载就会很高. 我的实现原理:定时任务读取任务,放到任务队列表中,然后使用线程池消费任务队列中的任务,每个线程时一直循环取任务. 我的定时任务周期是 1 分钟,线程池从初始化时,空闲线程存活的时间为 1 分

[Java Concurrency in Practice]第八章 线程池的使用

线程池的使用 8.1 在任务与执行策略之间的隐性耦合 虽然Executor框架为制定和修改执行策略提供了相当大的灵活性,但并非所有的任务都能适用所有的执行策略.有些类型的任务需要明确地执行执行策略,包括: 1. 依赖性任务:当线程池中运行任务都是独立的时,我们可以随意地修改池的长度与配置,这不会影响到性能以外的任何事情.但如果你提交到线程池中的任务依赖于其他的任务,这就会隐式地给执行策略带来了约束. 2. 非安全性任务:如果即使一个任务有线程安全性问题,只要它在单线程的环境下运行是不会有问题,如

高并发之——从源码角度分析创建线程池究竟有哪些方式

前言 在Java的高并发领域,线程池一直是一个绕不开的话题.有些童鞋一直在使用线程池,但是,对于如何创建线程池仅仅停留在使用Executors工具类的方式,那么,创建线程池究竟存在哪几种方式呢?就让我们一起从创建线程池的源码来深入分析究竟有哪些方式可以创建线程池. 使用Executors工具类创建线程池 在创建线程池时,初学者用的最多的就是Executors 这个工具类,而使用这个工具类创建线程池时非常简单的,不需要关注太多的线程池细节,只需要传入必要的参数即可.Executors 工具类提供了

22.线程池之ScheduledThreadPoolExecutor

1. ScheduledThreadPoolExecutor简介 ScheduledThreadPoolExecutor可以用来在给定延时后执行异步任务或者周期性执行任务,相对于任务调度的Timer来说,其功能更加强大,Timer只能使用一个后台线程执行任务,而ScheduledThreadPoolExecutor则可以通过构造函数来指定后台线程的个数.ScheduledThreadPoolExecutor类的UML图如下: 从UML图可以看出,ScheduledThreadPoolExecut

《java.util.concurrent 包源码阅读》14 线程池系列之ScheduledThreadPoolExecutor 第一部分

ScheduledThreadPoolExecutor是ThreadPoolExecutor的子类,同时实现了ScheduledExecutorService接口. public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService ScheduledThreadPoolExecutor的功能主要有两点:在固定的时间点执行(也可以认为是延迟执行),重复执行.