任务调度线程池

news/2024/10/23 9:37:25/

目录

 Timer  

 ScheduledExecutorService

正确处理执行任务异常 


 Timer  

在『任务调度线程池』功能加入之前,可以使用 java.util.Timer 来实现定时功能,Timer 的优点在于简单易用,但 由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个 任务的延迟或异常都将会影响到之后的任务。

public class Test {public static void main(String[] args) {Timer timer = new Timer();TimerTask task1 = new TimerTask() {@Overridepublic void run() {log.debug("task 1");sleep(2);}};TimerTask task2 = new TimerTask() {@Overridepublic void run() {log.debug("task 2");}};// 使用 timer 添加两个任务,希望它们都在 1s 后执行// 但由于 timer 内只有一个线程来顺序执行队列中的任务,//因此『任务1』的延时,影响了『任务2』的执行timer.schedule(task1, 1000);timer.schedule(task2, 1000);}}

输出

20:46:09.444 c.TestTimer [main] - start...

20:46:10.447 c.TestTimer [Timer-0] - task 1

20:46:12.448 c.TestTimer [Timer-0] - task 2  

 ScheduledExecutorService

线程池支持定时以及周期性执行任务,创建一个corePoolSize为传入参数,最大线程数为整形的最大数的线程池 

   public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {return new ScheduledThreadPoolExecutor(corePoolSize);}

ScheduledThreadPoolExecutor类的构造:

   public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,new DelayedWorkQueue());}
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);// 添加两个任务,希望它们都在 1s 后执行executor.schedule(() -> {System.out.println("任务1,执行时间:" + new Date());try { Thread.sleep(2000); } catch (InterruptedException e) { }
}, 1000, TimeUnit.MILLISECONDS);executor.schedule(() -> {System.out.println("任务2,执行时间:" + new Date());
}, 1000, TimeUnit.MILLISECONDS);

 输出

任务2,执行时间:Fri Jun 23 18:04:46 CST 2023
任务1,执行时间:Fri Jun 23 18:04:46 CST 2023

scheduleAtFixedRate 例子:

构造方法

    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);

 提交一个定期操作,该操作在给定的初始延迟后首先启用,随后在给定的时间段内启用;也就是说,执行将在 之后开始initialDelay,然后 、 initialDelay + 2 * period然后 initialDelay + period,依此类推。

ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);log.debug("start...");pool.scheduleAtFixedRate(() -> {log.debug("running...");
}, 1, 1, TimeUnit.SECONDS);

输出 

21:45:43.167 c.TestTimer [main] - start...

21:45:44.215 c.TestTimer [pool-1-thread-1] - running...

21:45:45.215 c.TestTimer [pool-1-thread-1] - running...

21:45:46.215 c.TestTimer [pool-1-thread-1] - running...

21:45:47.215 c.TestTimer [pool-1-thread-1] - running...

scheduleAtFixedRate 例子(任务执行时间超过了间隔时间):  

ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);log.debug("start...");pool.scheduleAtFixedRate(() -> {log.debug("running...");sleep(2);
}, 1, 1, TimeUnit.SECONDS);

输出分析:一开始,延时 1s,接下来,由于任务执行时间 > 间隔时间,间隔被『撑』到了 2s

21:44:30.311 c.TestTimer [main] - start...

21:44:31.360 c.TestTimer [pool-1-thread-1] - running...

21:44:33.361 c.TestTimer [pool-1-thread-1] - running...

21:44:35.362 c.TestTimer [pool-1-thread-1] - running...

21:44:37.362 c.TestTimer [pool-1-thread-1] - running...  

scheduleWithFixedDelay 例子: 

ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);log.debug("start...");pool.scheduleWithFixedDelay(()-> {log.debug("running...");sleep(2);
}, 1, 1, TimeUnit.SECONDS);

输出分析:一开始,延时 1s,scheduleWithFixedDelay 的间隔是 上一个任务结束 -> 延时 -> 下一个任务开始 所 以间隔都是 3s 

21:40:55.078 c.TestTimer [main] - start...

21:40:56.140 c.TestTimer [pool-1-thread-1] - running...

21:40:59.143 c.TestTimer [pool-1-thread-1] - running...

21:41:02.145 c.TestTimer [pool-1-thread-1] - running...

21:41:05.147 c.TestTimer [pool-1-thread-1] - running...

评价 整个线程池表现为:线程数固定,任务数多于线程数时,会放入无界队列排队。任务执行完毕,这些线 程也不会被释放。用来执行延迟或反复执行的任务

正确处理执行任务异常 

方法1:主动捉异常 

ExecutorService pool = Executors.newFixedThreadPool(1);
pool.submit(() -> {try {log.debug("task1");int i = 1 / 0;} catch (Exception e) {log.error("error:", e);}
})

方法2:使用 Future  

ExecutorService pool = Executors.newFixedThreadPool(1);Future<Boolean> f = pool.submit(() -> {log.debug("task1");int i = 1 / 0;return true;
});log.debug("result:{}", f.get());


http://www.ppmy.cn/news/545629.html

相关文章

计网学习记录

ps:答案可能不正确噢。 1.什么是计算机网络体系结构&#xff1f;什么是网络协议&#xff1f;协议的三要素是什么&#xff1f;每个要素的含义是什么&#xff1f; 计算机网络体系结构&#xff1a; 我看书上也没说清啊。。。 &#xff08;概念磨人啊&#xff09; 什么是计算机的…

区分 scanf和printf、fscanf和fprintf、sscanf和sprintf函数

文章目录 前言scanf和printffscanf和fprintfsscanf和sprintf总结 前言 C语言中&#xff0c;许多函数的函数名过于相似&#xff0c;使用者要是不能很好地区分这些函数&#xff0c;就会造成误用&#xff0c;最终导致代码的结果大相径庭。对于scanf和printf函数、fscanf和fprintf…

五一放假不想人挤人?下载植物大战僵尸中文版玩起来

植物大战僵尸中文版 for Mac推荐给大家&#xff01;此版本完美兼容macos big sur 11系统&#xff01;植物大战僵尸mac版将经典策略塔防玩法发挥到了极致&#xff0c;无论是防御方的植物种类&#xff0c;还是进攻的僵尸类型都非常丰富&#xff0c;游戏关卡多样&#xff0c;结合冒…

植物大战僵尸2 服务器维护时间,植物大战僵尸2:老玩家给平民党的7点忠告,不氪金也能玩到通关!...

植物大战僵尸从第1代开始&#xff0c;到现在的第2代&#xff0c;已经陪伴我们快要10年啦。小王子自己也是植物大战僵尸的铁忠粉&#xff0c;对于这款游戏也有一些自己的心得体会。如果你也是跟小王子一样&#xff0c;是个支持玩正版&#xff0c;不氪不肝的玩家&#xff0c;那么…

C语言实现植物大战僵尸自动收集阳光(三) 解决收集不全与收集奖杯卡死的问题

C语言实现植物大战僵尸自动收集阳光(一) 问题分析与寻找基址 C语言实现植物大战僵尸自动收集阳光(二) C语言控制台程序的实现 C语言实现植物大战僵尸自动收集阳光(三) 解决收集不全与收集奖杯卡死的问题 前言 上一篇中&#xff0c;我们已经用C语言通过对进程内存的读者操作&a…

用Java写一个植物大战僵尸简易版!

点击上方蓝色“程序猿DD”&#xff0c;选择“设为星标” 回复“资源”获取独家整理的学习资料&#xff01; 来源 | https://urlify.cn/byeEjy 有谁没玩过植物大战僵尸吗&#xff1f;用Java语言开发了自己的植物大战僵尸游戏。虽然系统相对简单&#xff0c;但是麻雀虽小五脏俱全…

Xcode 15 beta 2 (15A5161b) 发布下载 - Apple 平台 IDE (visonOS 1 beta 已发布)

Xcode 15 beta 2 (15A5161b) 发布下载 - Apple 平台 IDE (visonOS 1 beta 已发布) IDE for iOS/iPadOS/macOS/watchOS/tvOS/visonOS 此版本已加入 visonOS 支持。 请访问原文链接&#xff1a;https://sysin.org/blog/apple-xcode-15/&#xff0c;查看最新版。原创作品&#…

C++ 重制植物大战僵尸(Cocos2dx开源项目)

游戏简介&#xff1a; 此游戏全部由哔哩哔哩"尔领尔亿"&#xff08;LZ&#xff09;独立制作完成。此游戏与当前可以见到的众多改版不同。此程序不是基于原版游戏的二次开发&#xff0c;而是从新从零开始制作。该程序使用Cocos2dx游戏开发框架以及C语言制作完成。目…