java:定时任务以及线程池任务投递

血的教训-踩了定时线程池的坑 DelayQueue是一个无界的,用于放置实现了Delayed接口的对象,只能在到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。我们看一下延时队列// 当前任务创建时间// 延时时间// 初始化/*** 需要实现的接口,获得延迟时间(用过期时间-当前时间)*/@Override/*** 用于延迟队列内部比较排序(当前时间的延迟时间 - 比较对象的延迟时间)*/@Override生产端:投递消息时增加时间戳(当前时间+延时时间。 阅读详情

需求来源

有一套数据计算服务平台,基本架构是分布式文件系统 hdfs 存储原始数据,mysql 数据库存储计算模型路径 以及 任务记录。需要通过 hadoop 、spark等进行分布式任务计算。通过web 进行计算模型组织、任务投递以及结果查询。

解决问题

当任务投递到分布式计算系统之后,web 如何知道任务何时完成,如何获取任务计算结果(可能成功,也可能失败)

基本思想

实事上,分布式计算系统进行任务计算完成后,很难做到通知 web 已经完成任务。当然,有以下几种思路可以完成:

  • 有本事的可以通过修改 hadoop 或者 spark 源码定制一套消息通知 RESTAPI ,这样看起来很合理,但是难度可想而知
  • 在分布式计算系统中执行默认后台服务,定时捕捉计算任务完成,并通知webserver。这是很好的策略,但是意味着,除了部署分布式分布系统,还要根据 特定的 webserver 部署位置进行后台任务诸多配置。
  • 在分布式任务提交的同时,按照特定模板组织一个回调。将回调设置为任务进程退出时执行(不论是正常退出还是异常退出均执行),可以将任务计算结果写回webserver
  • 由webserver 执行定时任务,通过并发线程池投递向远程计算集群查询任务状态的任务,将查询到的结果写到数据库
web server 的定时任务

实际上,多数情况下使用后两种情况应该是比较好的。因为整个任务提交、监控都能由web server完成,计算集群只需要完成计算任务即可,而不用负责消息传递等。其中,又以 web server 的定时任务实现起来最为简单。
这里,有一个实现的例子,Spring Boot 的service 服务可以将任务投递到分布式集群、并将job 信息写入数据库,这里实现的是定时任务轮询数据库查询未完成的job ,然后向分布式计算系统发送请求判断任务是否真的完成,代码如下:

package com.IntelligenceInsight.Myth.util;

import com.IntelligenceInsight.Myth.mapper.JobMapper;
import com.IntelligenceInsight.Myth.model.Job;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Component
class TimerApplicationRunner implements ApplicationRunner {
    @Autowired
    private JobMapper mapper;

    // TODO: Should minimize access data
    // Stores a job without DONE in the cache and removes it from the cache when it detects completion
    // corresponding:
    // 1) When the web service starts, we need to access the database once to get the job without the done.
    // 2) Each time you submit a job, in addition to writing to the database, we need to write to the cache.
    @Override
    public void run(ApplicationArguments args) throws Exception {
        ThreadPool tp = new ThreadPool(128);
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                List<Job> jobs = mapper.JobListNotDone();
                for(Job job : jobs) {
                    Task task = new Task(job.getUuid());
                    tp.IssueOperation(task);
                }
            }
        },1000,3000);
    }
}

class Task implements Runnable {
    private String uuid;

    public Task(String uuid) {
        this.uuid = uuid;
    }

    public void run() {
        // 根据 uuid 去检查 job 的状态
        // 主要是去检查任务执行结果的写入内容,并将状态值更新到数据库
        // job 状态有四种 SUBMIT  RUNNING   FINISH  FAIL

        System.out.println(uuid);
    }
}


public class ThreadPool {
    private ExecutorService es;

    public ThreadPool(int workers) {
        ExecutorService es = Executors.newFixedThreadPool(workers);
        this.es = es;
    }

    public void IssueOperation(Runnable task) {
        this.es.submit(task);
    }
}

原理详解

解释一下实现,以及web server 所用架构:
后台框架是 Spring Boot 2 + Mybatis 。
这里实现的是:

  • 当web server 启动的时候 通过 ApplicationRunner 启动一个同步进程,
  • 同步进程主要做的就是,声明一个线程池,然后通过 new Timer().schedule() 启动一个定时任务,
  • 定时任务通过查询数据库找到所有没有完成的任务,
  • 将任务所持有的uuid 构建一个task,并定义task 需要做的事情
  • task 需要的做的事情:向计算平台发一个查询文件操作,并将查询的结果写回到数据库
  • 将 task 投递到并发线程池
小结

web server 的轮询操作,虽然基本实现需求。但并不能保证线程安全。
在不修改hadoop 等源码的前提下,最好的方式应该是想办法增加回调,既能保证任务状态的即时性,又能避免不断轮询计算集群造成的资源占用。

Java中使用线程池实现定时任务调度 ScheduledExecutorService是ExecutorService的一个子接口,它提供了一些额外的方法来支持定时任务的调度。线程池是一种用于管理和重用线程的机制,它可以有效地管理线程的生命周期,避免频繁地创建和销毁线程,提高程序的性能和效率。下面我们将详细介绍如何在Java中使用线程池来实现定时任务调度,并附上相应的源代码。首先,我们需要创建一个线程池来执行我们的定时任务。Java提供了Executor框架来管理线程池,我们可以使用Executors类中的静态方法来创建线程池。 阅读详情

相关推荐

MacBook用户必看:用Homebrew一键搞定frp内网穿透(含阿里云配置模板)

本文为MacBook用户提供基于Homebrew的frp内网穿透实战指南,详细介绍了从环境准备到阿里云服务器配置的全过程。通过Homebrew一键安装frp客户端,结合阿里云配置模板,实现高效稳定的内网穿透,适用于远程开发、IoT设备调试等多种场景。

weixin_28692817的博客 321

11.定时任务&定时线程池详解

当我们不用任务框架时,我们想自己写一个定时任务时,我们能想起那个工具类呢?Timer ?还有吗?不知道了,下面我们要讲下ScheduledThreadPoolExecutor,定时任务线程池,可以执行一次任务,还可以执行周期性任务。

Mao_yafeng的博客 7419

VsCode安装和配置c/c++环境(超完整,小白专用)

1. vsCode配置C/C++环境 1. vsCode下载和安装 1. 下载Microsoft vsCode [vsCode在这里插入图片描述官网下载: https://code.visualstudio.com/ 2. 安装vsCode 3. 下载中文插件 我这边已经下载过,刚卸载但是没有重启编译器,所以界面显示了中文 2. MinGW编译器下载和配置 1. 下载MinGW 在线安装——下载MinGW-W64-install.exe(速度慢) 下载压缩包——×86_64-posix-

黄化的多多 60万+

定时任务--线程池

定时任务线程池是一种基于线程池的定时执行任务的机制。它使用线程池来管理和调度任务的执行,可以避免创建大量的线程,提高系统的效率和性能。总结:Java提供了ScheduledThreadPoolExecutor类来实现定时任务线程池。该类继承自ThreadPoolExecutor类,具有线程池的特性,并且可以定时执行任务。在创建ScheduledThreadPoolExecutor对象时,可以设置线程池的核心线程数和最大线程数。

Flying_Fish_roe的博客 2331

保姆级CVE-2018-17066漏洞复现 DLink命令注入漏洞(更新完结)

之后按照之前复现的方式一样 我们丢到kali中执行binwalk解析。之后为了模拟 可以在kali里安装qemu-mipsel。在bin目录下可以尝试将goahead的环境搭配好。固件官网可以进行下载。

weixin_51339377的博客 883

ITK-snap进行分割区域标注、三维显示及改变显示颜色

在进行医学图像器官分割时,无论我们是用传统方法还是深度学习,最后肯定要用到手动分割的区域作为金标准来验证我们方法的精度。但是手动标注器官的轮廓是十分耗时的,这里我介绍一个比较简单的标注方法,以肺分割作为例子。 我们使用ITK-snap作为分割标注工具。 当切片间距离比较小时,比如1mm,一个患者的完整HRCT序列通常在200张以上,如果让医生一一进行分割区域标注是非常耗时乏味的。因此,我们可以使用最简单的阈值法比如OSTU,加上基本的形态学操作对肺进行粗分割得到粗略的分割掩码,在此基础上再手动的对分割结果进

u010409517的博客 2万+

线程池的使用-定时任务

线程池概念﹔ 其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。 线程池的底层原理 线程池的使用 线程池:JDK1.5之后提供的 Java.util.concurrent.Executors:线程池的工厂类,用来生成线程池 Executors类中的静态方法: static ExecutorService newFixedThreadPool(int nThreads)创建一个可重用固定线程数的线程池 参数: int nThreads:创建

好好学习 2446

图学习——04.HAN(异构图注意力网络)

什么是异构图,什么是元路径,什么是HAN,怎么计算attention,节点级别的attention和语义级别的attention

m0_51474171的博客 3001

java线程池、定时任务

目录标题一、自定义线程池二、java提供的四种线程池三、java定时任务 一、自定义线程池 参考 package threadPool; import java.util.Date; import java.util.concurrent.*; /** * * 自定义线程池。 * ThreadPoolExecutor<b>构造参数如下</b><br/> * * int corePoolSize, 核心线程大小(当前最大并行运行线程数)<br/>

a123123sdf的博客 3652

提示词注入攻击全面解析与防御策略

提示词注入(Prompt Injection)是指攻击者通过精心构造的输入内容,操纵或欺骗AI系统执行非预期行为的技术手段。这种攻击类似于传统的SQL注入或XSS攻击,但其目标是AI模型的提示词处理机制而非数据库或网页。提示词注入利用了大语言模型的一个基本特性:它们被设计为遵循指令。攻击者通过在用户输入中嵌入特定指令,试图覆盖或绕过系统原有的安全限制和行为规则,让模型执行本不应该执行的操作。深度防御:实施多层次防御策略,不依赖单一安全措施持续更新:随着攻击技术的发展不断更新防御措施安全设计优先。

免责声明:本资料部分整理自合法网络公开渠道,部分为个人学习积累成果,仅作学习参考、学术交流使用。所收费用仅为资料搜集整理的时间劳务酬劳。版权归原作者及出版方所有,本人不承担相关版权及内容法律责任,若有侵权请告知,即刻删除处理。 4210

FM20S用户手册--Linux系统启动卡制作及系统固化

评估板出厂时,默认提供一张配套的Micro SD卡,此卡为可正常使用的Linux系统 启动卡。评估板断电,将Linux系统启动卡插入评估板Micro SD卡槽,根据评估底板丝印将 启动方式选择拨码开关拨为1010(1-4).此档位为Micro SD启动模式。使用Linux 系统启动卡启动系统时,将使用此目录的BOOTbn文件启动FSBL和U-Boot。Linux系统启动卡制作时,已将固化系统的脚本文件mkemmcboot.sh拷贝至Linux系 统启动卡文件系统的"/opt/tools/"目录下。

创龙,嵌入式一体化解决方案商 302

浅谈 Java 异步重试机制:保证「事务提交后再发消息」,失败自动重试

在分布式系统里,我们经常会遇到这类需求:下完单,要异步通知积分服务加积分、通知库存服务扣库存、通知风控服务做校验……最常见的做法是:在本地事务里「写完业务数据,紧接着发一条 MQ 消息」。但很多在这里栽过跟头——消息发出去了,本地事务却回滚了,于是出现「消息说订单已支付,数据库里却没有订单」的数据不一致。消息一定要在「本地事务提交成功之后」再发送;并且,为了防止 MQ 短暂抖动导致消息丢失,发送动作本身还要带重试。为什么不能在事务里「先发消息」

鲜衣怒马少年时,不负韶华行且知。 从第一个Hello World起,便踏上这条后端修行路。趟过分布式事务的浑水,翻过性能瓶颈的高山,方知代码如剑,需千锤百炼方显锋芒。 博客所记,皆为修行路上的顿悟与磕绊,愿与同道人共勉,稳步江湖。 596

【数据集】全球湿度数据集总结

【数据集】全球湿度数据集总结

WW、forever的博客 1662

@Java中实现定时任务

创建 java.util.TimerTask 任务,在 run 方法中实现业务逻辑。通过 java.util.Timer 进行调度,支持按照固定频率执行。所有的 TimerTask 是在同一个线程中串行执行,相互影响。也就是说,对于同一个 Timer 里的多个 TimerTask 任务,如果一个 TimerTask 任务在执行中,其它 TimerTask 即使到达执行的时间,也只能排队等待。如果有异常产生,线程将退出,整个定时任务就失败。}}

weixin_49329785的博客 3694

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Java线程池

固定线程池。该线程池固定线程数量,不会增加或减少线程,适用于执行数量已知的任务。核心线程数是固定的,没有线程竞争。单例线程池。该线程池只有一个线程,用于按顺序执行任务。任务会按照提交的顺序依次执行,保持了任务的顺序性。缓存线程池。该线程池可以根据需要创建新线程,适用于执行大量的短期任务。一个可以无限扩大的线程池,比较适合处理执行时间比较小的任务。任务的执行顺序可能不同于提交顺序,取决于线程的可用性。定时线程池。该线程池用于定时执行任务,例如定时任务调度。

weixin_43763430的博客 1303

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

踩了定时线程池的坑,导致公司损失几千万,血的教训

大家好呀,上周我们公司由于定时线程池使用不当出了一个故障,几千万的单子可能没了。给兄弟们分享分享这个坑,希望兄弟们以后别踩!业务中大量的使用定时线程池(ScheduledExecutorService)执行任务,有时候会忽略掉 Try/Catch 的异常判断。当任务执行报错时,会导致整个定时线程池挂掉,影响业务的正常需求。

爱敲代码的小黄 2976

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

quartz 分布式_分布式定时任务调度系统技术选型

作者:sharedCode链接:https://blog.youkuaiyun.com/u012394095/article/details/79470904我们先思考下面几个业务场景的解决方案:支付系统每天凌晨1点跑批,进行一天清算,每月1号进行上个月清算电商整点抢购,商品价格8点整开始优惠12306购票系统,超过30分钟没有成功支付订单的,进行回收处理商品成功发货后,需要向客户发送短信提醒类似的业务场景非...

weixin_39866774的博客 792

JDK定时线程池源码解读

最近在研究线程池的底层原理时,忽然想起来之前遇到的一个面试题:“你可以自己手写一个可定时的线程池吗?” 转念一想,spring的定时任务不就是干这个的吗?所以当时想的是采用Timer的方式去处理,面试官不是很满意,反问:“Timer的底层有了解过吗?”场面陷入尴尬,犹豫了一会儿,只能红着脸败下阵来。 JDK自带的线程池有四种,大家耳熟能详。其中固定长度、缓存以及单例的实现方案对比定时线程池较为简单,大家可以自行研究。本文主要分享记录帝都的雁在研究定时线程池源码时的一些思路和理解。 分享之前,需.

帝都的雁的博客 427

jdk线程池

首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。但是如果直接采用JDK提供的方式去构建,可以设置的核心参数最多就两个,这样就会导致对线程池的控制粒度很粗。所以在阿里规范中也推荐自己去自定义线程池。手动的去new ThreadPoolExecutor设置他的一些核心属性。自定义构建线程池,可以细粒度的控制线程池,去管理内存的属性,并且针对一些参数的设置可能更好的在后期排查问题。

m0_68705273的博客 560

线程池源码

首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都有决定性的作用。但是如果直接采用JDK提供的方式去构建,可以设置的核心参数最多就两个,这样就会导致对线程池的控制粒度很粗。所以在阿里规范中也推荐自己去自定义线程池。手动的去new ThreadPoolExecutor设置他的一些核心属性。自定义构建线程池,可以细粒度的控制线程池,去管理内存的属性,并且针对一些参数的设置可能更好的在后期排查问题。

埃泽漫笔 1011

Java并发编程(线程池、并发集合)详解

为什么要使用线程池在开发中,为了提升效率的操作,我们需要将一些业务采用多线程的方式去执行。比如有一个比较大的任务,可以将任务分成几块,分别交给几个线程去执行,最终做一个汇总就可以了。比如做业务操作时,需要发送短信或者是发送邮件,这种操作也可以基于异步的方式完成,这种异步的方式,其实就是再构建一个线程去执行。但是,如果每次异步操作或者多线程操作都需要新创建一个线程,使用完毕后,线程再被销毁,这样的话,对系统造成一些额外的开销。在处理过程中到底由多线程处理了多少个任务,以及每个线程的开销无法统计和管理。所以咱们

yqqの博客 800

并发编程 - 线程池

1、首先ThreadPoolExecutor中,一共提供了7个参数,每个参数都是非常核心的属性,在线程池去执行任务时,每个参数都起决定性的作用。2、但是如果直接采用JDK提供的方式去构建,可以设置的核心参数最多就两个,这样就会导致对线程池的控制粒度很粗。所以在阿里规范中也推荐自己去自定义线程池。手动的去new ThreadPoolExecutor设置他的一些核心属性。3、自定义构建线程池,可以细粒度的控制线程池,去管理内存的属性,并且针对一些参数的设置可能更好的在后期排查问题。

weixin_49622776的博客 1397

C++定时任务调度:Bosma::Scheduler库实战指南

任务调度是计算机系统中实现自动化执行的核心机制,其原理基于时间触发与事件驱动模型。通过预定义的时间规则,系统能够自动执行特定操作,这一技术价值在于提升程序自动化程度与资源利用率。在C++开发中,任务调度广泛应用于日志清理、心跳包发送、数据备份等场景。传统手动实现方式往往面临代码冗余与维护困难,而Bosma::Scheduler库提供了基于Cron表达式的轻量级解决方案。该库采用线程池与时间轮算法,支持动态任务管理,并能有效处理Cron表达式解析与任务生命周期等复杂问题。对于需要实现微服务定时组件或物联网设备

weixin_30527323的博客 457

springboot定时任务@Scheduled(1)

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门,即可获取!1.在springboot启动类上配置@EnableScheduling 这个一定要加上;否则,不会定时启动任务!2.在你的方法上添加@Scheduled@Scheduled中的参数说明:@Scheduled(fixedRate=2000):上一次开始执行时间点后2秒再次执行; @Scheduled(fixedDelay=2000):上一次执行完毕时间点后2秒再次执行; @Scheduled(initialD

2301_76238237的博客 1159

线程池

线程池

爱笑的boy的博客 393

分布式定时任务框架选型

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天14:00更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2021超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框架 Netty 源码解析消息中间件 RocketMQ 源码解析数据库中间件 Sharding-JDBC 和 MyCAT 源码解析作业调度中间件 Elast...

weixin_44421461的博客 179
上一篇: docker:配置docker pull 源
下一篇: conda:pytorch开发环境搭建
github_37320188
博客等级 码龄10年 24粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值