java线程池 - ScheduledThreadPoolExe

2020-07-09  本文已影响0人  zbsong

什么是ScheduledThreadPoolExecutor?

在给定的延迟之后运行任务或者是定期执行任务
本文只简单描述一下怎么使用,不涉及原理和源码,可以简单了解后自己去撸源码。

构造

ScheduledThreadPoolExecutor(int corePoolSize)
ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)

ScheduledThreadPoolExecutor方法

类型 方法 描述
protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) 修修改或替换用于执行可运行的任务
protected <V> RunnableScheduledFuture<V> decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) 修改或替换用于执行可运行的任务
void execute(Runnable command) 零延迟执行命令
boolean getContinueExistingPeriodicTasksAfterShutdownPolicy() 获取执行程序已关闭是否继续执行现有定期任务的策略
boolean getExecuteExistingDelayedTasksAfterShutdownPolicy() 获取执行程序已关闭是否执行现有延迟任务的策略
BlockingQueue<Runnable> getQueue() 返回执行程序使用的任务队列
boolean getRemoveOnCancelPolicy() 获取在取消时是否应立即从工作队列中删除已取消任务的策略
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) 创建并执行一次操作,该操作在给定延迟后启用
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 创建并执行一个周期性操作,该操作在给定的初始延迟后首先启用,然后在给定的时间后再次启用,即第一次是initialDelay后执行,第二次是initialDelay + period后执行,第三次是 initialDelay + period*2 后执行,依次类推
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) 创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在一次执行的终止后开始,delay后开始执行下一次
void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) 设置执行程序关闭是否继续执行现有定期任务的策略
void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) 设置关闭后执行程序是否也执行现有延迟任务的策略
void setRemoveOnCancelPolicy(boolean value) 设置取消时任务时是否应立即从工作队列中删除已取消任务的策略
void shutdown() 启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务
List<Runnable> shutdownNow() 尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表
<T> Future<T> submit(Callable<T> task) 提交有返回值的Callable任务
Future<?> submit(Runnable task) 提交有返回值的Runnable任务
<T> Future<T> submit(Runnable task, T result) 提交有返回值的Callable任务

ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,所以也继承了ThreadPoolExecutor方法,ThreadPoolExecutor有哪些方法可以去Java API规范中去查看,也可以到java线程池 - ThreadPoolExecutor中查看。

例子

package com.sy.thread.example;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;

/**
 * Description: thread
 *
 * @author songyu
 */
public class ScheduledThreadPoolExecutorTest {
    public static void main(String[] args) throws Exception {
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //创建线程池
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
            //根据需要重写方法
        };
        //没有返回值的任务
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                LocalDateTime now = LocalDateTime.now();
                System.out.println(now.format(fmTime) + " Runnable开始执行");
            }
        });
        //schedule(Runnable command, long delay, TimeUnit unit)
        //延迟2秒执行,没有返回值
        LocalDateTime now1 = LocalDateTime.now();
        System.out.println(now1.format(fmTime) + " 将Runnable延迟任务加入线程池,一秒后开始执行");
        executor.schedule(thread,2, TimeUnit.SECONDS);
    }
}

执行结果

2020-07-09 14:48:16 将Runnable延迟任务加入线程池,一秒后开始执行
2020-07-09 14:48:18 Runnable开始执行
package com.sy.thread.example;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;

/**
 * Description: thread
 *
 * @author songyu
 */
public class ScheduledThreadPoolExecutorTest2 {
    public static void main(String[] args) throws Exception {
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //创建线程池,、
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
            //根据需要重写方法
        };

        //有返回值的任务
        Callable callable = new Callable() {
            @Override
            public Object call() throws Exception {
                LocalDateTime now = LocalDateTime.now();
                System.out.println(now.format(fmTime) + " Callable开始执行");
                return "hello world";
            }
        };

        //schedule(Callable<V> callable, long delay, TimeUnit unit)
        //延迟五秒执行 有返回值
        LocalDateTime now2 = LocalDateTime.now();
        System.out.println(now2.format(fmTime) + " 将Callable延迟任务加入线程池,一秒后开始执行");
        Future future = executor.schedule(callable,5, TimeUnit.SECONDS);
        System.out.println("Callable任务返回内容为:" + future.get());
    }
}

执行结果

2020-07-09 14:54:49 将Callable延迟任务加入线程池,一秒后开始执行
2020-07-09 14:54:54 Callable开始执行
Callable任务返回内容为:hello world
package com.sy.thread.example;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Description: thread
 *
 * @author songyu
 */
public class ScheduledThreadPoolExecutorTest3 {
    public static void main(String[] args) {
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //创建线程池
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
            //根据需要重写方法
        };

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                LocalDateTime now = LocalDateTime.now();
                System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
            }
        });
        //scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
        //initialDelay 第一次延迟执行时间
        //period 周期时间
        //将任务提交到线程池,5秒后执行第一次任务,然后每隔10s执行一次
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
        executor.scheduleAtFixedRate(thread,5,10, TimeUnit.SECONDS);
    }
}

执行结果

2020-07-09 15:05:17 将Runnable周期任务加入线程池,一秒后开始执行
2020-07-09 15:05:22 Runnabled周期任务开始执行
2020-07-09 15:05:32 Runnabled周期任务开始执行
2020-07-09 15:05:42 Runnabled周期任务开始执行
2020-07-09 15:05:52 Runnabled周期任务开始执行
2020-07-09 15:06:02 Runnabled周期任务开始执行
2020-07-09 15:06:12 Runnabled周期任务开始执行
2020-07-09 15:06:22 Runnabled周期任务开始执行
2020-07-09 15:06:32 Runnabled周期任务开始执行
......
package com.sy.thread.example;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Description: thread
 *
 * @author songyu
 */
public class ScheduledThreadPoolExecutorTest4 {
    public static void main(String[] args) {
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        //创建线程池
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
            //根据需要重写方法
        };

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    LocalDateTime now = LocalDateTime.now();
                    System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
                    Random random = new Random();
                    int randomNumber1 = random.nextInt(10) * 1000;
                    System.out.println("阻塞" + randomNumber1 + "毫秒");
                    Thread.sleep(randomNumber1);
                    LocalDateTime now2 = LocalDateTime.now();
                    System.out.println(now2.format(fmTime) + " Runnabled周期任务执行结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
        //initialDelay 第一次延迟执行时间
        //period 周期时间
        //将任务提交到线程池,5秒后执行第一次任务,第一次执行完成后,10秒后执行下一次,除了第一次执行,后续的执行都是从上一个任务完成后开始算,period时间后执行
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
        executor.scheduleWithFixedDelay(thread,5,10, TimeUnit.SECONDS);
    }
}

执行结果

2020-07-09 15:26:04 将Runnable周期任务加入线程池,一秒后开始执行
2020-07-09 15:26:09 Runnabled周期任务开始执行
阻塞8000毫秒
2020-07-09 15:26:17 Runnabled周期任务执行结束
2020-07-09 15:26:27 Runnabled周期任务开始执行
阻塞3000毫秒
2020-07-09 15:26:30 Runnabled周期任务执行结束
2020-07-09 15:26:40 Runnabled周期任务开始执行
阻塞8000毫秒
2020-07-09 15:26:48 Runnabled周期任务执行结束
2020-07-09 15:26:58 Runnabled周期任务开始执行
阻塞9000毫秒
2020-07-09 15:27:07 Runnabled周期任务执行结束
2020-07-09 15:27:17 Runnabled周期任务开始执行
阻塞1000毫秒
2020-07-09 15:27:18 Runnabled周期任务执行结束
2020-07-09 15:27:28 Runnabled周期任务开始执行
......

ScheduledThreadPoolExecutor的execute()和submit()

execute() > schedule(Runnable command, long delay, TimeUnit unit)
submit() > schedule(Callable<V> callable, long delay, TimeUnit unit)

public void execute(Runnable command) {
  schedule(command, 0, NANOSECONDS);
}

public Future<?> submit(Runnable task) {
  return schedule(task, 0, NANOSECONDS);
}

上面几个简单的例子把ScheduledThreadPoolExecutor几种任务执行的方式都简单的实现了一下,自己可以扩展一下,然后把剩余的方法和学习一下。

上一篇下一篇

猜你喜欢

热点阅读