JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 任务调度线程池 定时任务 / 延时执行(ScheduledThreadPoolExecutor 延时执行 / 定时执行)(代

Posted Z && Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 任务调度线程池 定时任务 / 延时执行(ScheduledThreadPoolExecutor 延时执行 / 定时执行)(代相关的知识,希望对你有一定的参考价值。

1. 任务调度线程池


1.1 ScheduledThreadPoolExecutor 延时执行

示例代码(任务都延时1s执行):

package com.tian;

import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class TestTimer {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
        // 添加两个任务,希望它们都在 1s 后执行
        System.out.println("当前时间:     " + new Date().toLocaleString());
        executor.schedule(() -> {
            System.out.println("任务1执行时间:" + new Date().toLocaleString());
            try {
                Thread.sleep(5000);
                System.out.println("任务1执行完毕" + new Date().toLocaleString());
            } catch (InterruptedException e) {
            }
        }, 1000, TimeUnit.MILLISECONDS);
        executor.schedule(() -> {
            System.out.println("任务2执行时间:" + new Date().toLocaleString());
            System.out.println("任务2执行完毕" + new Date().toLocaleString());
        }, 1000, TimeUnit.MILLISECONDS);
    }
}

运行结果:


1.2 ScheduledThreadPoolExecutor 定时执行


1.2.1 scheduleAtFixedRate


1.2.1.1 任务执行时间小于周期(周期不变)

在1s后执行任务 之后每2s执行一次任务

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "TestTimer")
public class TestTimer {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        log.debug("start...");
        // 在1s后执行任务 之后每2s执行一次任务
        pool.scheduleAtFixedRate(() -> {
            log.debug("running...");
        }, 1, 2, TimeUnit.SECONDS);
    }
}

运行结果:


1.2.2.2 任务执行时间大于周期(此时周期为任务的执行时间)

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "TestTimer")
public class TestTimer {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        log.debug("start...");
        // 在1s后执行任务 之后每2s执行一次任务
        pool.scheduleAtFixedRate(() -> {
            log.debug("running...");
            try {
                // 任务休眠时间(3s)大于执行周期(2s)
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, 1, 2, TimeUnit.SECONDS);
    }
}

运行结果:


1.2.2.3 当任务执行遇到异常时(程序会一直停留在异常这里)

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "TestTimer")
public class TestTimer {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        log.debug("start...");
        // 在1s后执行任务 之后每2s执行一次任务
        pool.scheduleAtFixedRate(() -> {
            log.debug("running...");
            int number = 1 / 0;
        }, 1, 2, TimeUnit.SECONDS);
    }
}

执行结果:


1.3.2 scheduleWithFixedDelay

记住: scheduleWithFixedDelay中任务真正的执行周期为: 任务的执行时间 + 执行周期

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j(topic = "TestTimer")
public class TestTimer {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
        log.debug("start...");
        pool.scheduleWithFixedDelay(() -> {
            log.debug("running...");
            try {
                // 任务睡眠5s
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 任务在1s后执行 执行周期为2s
        }, 1, 2, TimeUnit.SECONDS);
    }
}

其余的和scheduleAtFixedRate类似,多说无益



以上是关于JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 任务调度线程池 定时任务 / 延时执行(ScheduledThreadPoolExecutor 延时执行 / 定时执行)(代的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 JUC Semaphore(信号量) -- 介绍 & 使用

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 正确处理线程池异常

JUC并发编程 共享模式之工具 JUC ConcurrentHashMap -- ConcurrentHashMap的错误使用和正确使用(示例:统计单词个数)

JUC并发编程 共享模式之工具 JUC Semaphore(信号量) -- Semaphore原理

JUC并发编程 共享模式之工具 JUC 线程安全的集合类 -- 线程安全的集合类概述

JUC并发编程 共享模式之工具 ThreadPoolExecutor -- 线程池应用之定时任务(在每周周四执行定时任务)