前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >任务调度线程池

任务调度线程池

作者头像
一个风轻云淡
发布于 2023-10-15 03:11:03
发布于 2023-10-15 03:11:03
21800
代码可运行
举报
文章被收录于专栏:java学习javajava学习java
运行总次数:0
代码可运行
 Timer  

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Test {
    public static void main(String[] args) {
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() {
            @Override
            public void run() {
                log.debug("task 1");
                sleep(2);
            }
        };
        TimerTask task2 = new TimerTask() {
            @Override

            public 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为传入参数,最大线程数为整形的最大数的线程池

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }

ScheduledThreadPoolExecutor类的构造:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 例子:

构造方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 例子(任务执行时间超过了间隔时间):  

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 例子: 

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:主动捉异常 

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ExecutorService pool = Executors.newFixedThreadPool(1);
pool.submit(() -> {
 try {
     log.debug("task1");
     int i = 1 / 0;
 } catch (Exception e) {
     log.error("error:", e);
 }
})

方法2:使用 Future  

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ExecutorService pool = Executors.newFixedThreadPool(1);

Future<Boolean> f = pool.submit(() -> {
     log.debug("task1");
     int i = 1 / 0;
     return true;
});

log.debug("result:{}", f.get());
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-09-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JUC内置线程池
整个线程池表现为线程数会根据任务量不断增长,没有上限,当任务执行完毕,空闲 1分钟后释放线程。 适合任务数比较密集,但每个任务执行时间较短的情况。
兜兜转转
2023/03/08
1740
JUC内置线程池
JUC学习笔记——并发工具线程池
如果想要解除之前的饥饿现象,正确的方法就是采用Worker Thread模式为他们分配角色,让他们只专属于一份工作:
秋落雨微凉
2022/11/21
4190
JUC学习笔记——并发工具线程池
JUC学习之共享模型之工具上之线程池浅学
ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量
大忽悠爱学习
2022/01/10
4350
JUC学习之共享模型之工具上之线程池浅学
四种任务调度的 Java 实现 转
 java.util.Timer 了,它是最简单的一种实现任务调度的方法,下面给出一个具体的例子:
wuweixiang
2018/08/14
7650
【JUC基础】13. 线程池(二)
Executors类是Java并发工具包(java.util.concurrent)中提供的一个工具类,用于创建和管理线程池。它提供了一些静态方法,用于创建不同类型的线程池,简化了线程池的创建和配置过程。
有一只柴犬
2024/01/25
1990
【JUC基础】13. 线程池(二)
使用ScheduledExecutorService代替下Timer
1.scheduledExecutorService类方法scheduleAtFixedRate,ScheduleWithFixedDelay区别比较
oktokeep
2024/10/09
1220
Java多线程学习(八)线程池与Executor 框架
Java面试通关手册(Java学习指南,欢迎Star,会一直完善下去,欢迎建议和指导):https://github.com/Snailclimb/Java_Guide
用户2164320
2018/07/08
1.1K0
Java多线程学习(八)线程池与Executor 框架
(80) 定时任务的那些坑 / 计算机程序的思维逻辑
本节探讨定时任务,定时任务的应用场景是非常多的,比如: 闹钟程序或任务提醒,指定时间叫床或在指定日期提醒还信用卡 监控系统,每隔一段时间采集下系统数据,对异常事件报警 统计系统,一般凌晨一定时间统计昨日的各种数据指标 在Java中,有两种方式实现定时任务: 使用java.util包中的Timer和TimerTask 使用Java并发包中的ScheduledExecutorService 它们的基本用法都是比较简单的,但如果对它们没有足够的了解,则很容易陷入其中的一些陷阱,下面,我们就来介绍它们
swiftma
2018/01/31
1.2K0
Java线程池了解一下?
其实常用Java线程池本质上都是由ThreadPoolExecutor或者ForkJoinPool生成的,只是其根据构造函数传入不同的实参来实例化相应线程池而已。
技术从心
2019/08/07
4160
java高并发系列 - 第19天:JUC中的Executor框架详解1
Executors框架是Doug Lea的神作,通过这个框架,可以很容易的使用线程池高效地处理并行任务。
路人甲Java
2019/12/10
8430
从简单到复杂学习任务调度(1)
今天来分享一下任务调度,任务调度在我们项目中是不可避免的,只是不同的场景,不同的业务复杂程度和业务要求,我们会使用不同的任务调度实现,而任务调度的实现方式以及框架有很多,在Java语言层面,可以使用Timer类来实现,也可以使用定时线程池ScheduledExecutorService来实现,如果使用Spring框架,可以使用注解@Scheduled配合CRON表达式来实现任务调度,现成的框架我们可以使用Quartz,xxl-job,Elastic-Job,PowerJob等。
小四的技术之旅
2023/03/02
4980
从简单到复杂学习任务调度(1)
Java线程池分析
在执行一个异步任务或并发任务时,往往是通过直接new Thread()方法来创建新的线程,这样做弊端较多,更好的解决方案是合理地利用线程池,线程池的优势很明显,如下:
九州暮云
2019/08/21
4410
Java线程池分析
线程池如何创建线程_创建线程池的七个参数
Executors 类是从 JDK 1.5 开始就新增的线程池创建的静态工厂类,它就是创建线程池的,但是很多的大厂已经不建议使用该类去创建线程池。原因在于,该类创建的很多线程池的内部使用了无界任务队列,在并发量很大的情况下会导致 JVM 抛出 OutOfMemoryError,直接让 JVM 崩溃,影响严重。
全栈程序员站长
2022/11/10
1.2K0
一文学会线程池、任务调度的使用
用户7630333
2023/12/07
2780
一文学会线程池、任务调度的使用
重学 Java 线程基础之线程池
线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。
啵啵肠
2023/11/28
2110
(五)四种线程池底层详解
可以看到corePoolSize、maximumPoolSize都是 1 ,keepAliveTime 是 0 ,使用的是LinkedBlockingQueue队列。
HaC
2020/12/30
5240
Java并发之ScheduledExecutorService(schedule、scheduleAtFixedRate、scheduleWithFixedDelay)
项目地址:https://github.com/windwant/windwant-demo/tree/master/thread-demo
WindWant
2020/09/11
9630
线程池整理
一般在生产环境中,我们都不会直接new一个Thread,然后再去start(),因为这么做会不断频繁的创建线程,销毁线程,过大的线程会耗尽CPU和内存资源,大量的垃圾回收,也会给GC带来压力,延长GC停顿时间.
算法之名
2019/08/20
5980
线程池
线程池的作用: 线程池作用就是限制系统中执行线程的数量。      根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。 为什么要用线程池: 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行
汤高
2018/01/11
1K0
JDK1.8 创建线程池有哪几种方式?
定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
猫头虎
2024/04/07
1440
推荐阅读
相关推荐
JUC内置线程池
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验