范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

线程池里的定时任务跑的可欢了,可咋停掉特定的任务?

  客户端抢到分布式锁之后开始执行任务,执行完毕后再释放分布式锁。持锁后因客户端异常未能把锁释放,会导致锁成为永恒锁。为了避免这种情况,在创建锁的时候给锁指定一个过期时间。到期之后锁会被自动删除掉,这个角度看是对锁资源的一种保护。重点:但若锁过期被删除后,任务还没结束怎么办?可以通过在一个额外的线程中主动推迟分布式锁的过期时间,下文也用续期一词来表述;避免当任务还没执行完,锁就被删除了。但当分布式锁很多的情况下,每个锁都配置一个线程着实浪费,所以是否可以用线程池里的定时任务呢?
  在《【自省】使用Executors.xxx违反阿里Java代码规范,那还不写定时任务了?》 中仍然通过【自省】的方式讨论了也可以使用 ScheduledExecutorService#scheduleAtFixedRate来实现定时任务,它的运行机制大概是这样:如果上一个任务的执行时间大于等待时间,任务结束后,下一个任务马上执行。如果上一个任务的执行时间小于等待时间,任务结束后,下一个任务在(间隔时间-执行时间)后开始执行。二、理还乱?
  用 ScheduledExecutorService#scheduleAtFixedRate逻辑看很简单,也很清晰,但任何事情都有两面性,把任务丢给线程池的方式,实现起来自然简单清晰,但肯定也有弊端。如果要把锁的功能做的健壮,总要从不断地自我质疑、自我反思中,理顺思路,寻找答案,我认为这属于自省式学习,以后也想尝试这种模式,一起再看看有啥问题:问题:锁主动释放的时候,续期的任务要关闭嘛?是的,当锁被用户主动关闭的时候,主动续期的任务是要主动取消掉的。问题:如果我不主动取消呢?对于不主动续期的锁,抢锁后配置一个合适的过期时间,到期之后锁自然会被释放;这种情况下,客户端本就没有续期任务需要取消。但如果有额外的线程|线程池在定时续期的话,锁用完了需要被释放掉,任务一定要主动取消掉。问题:可万一忘记了呢?有加锁解锁的代码模板,按照模板来;获取锁之后,在finally中执行释放锁的操作。boolean lockResult = lockInstance.tryLock();  if(lockResult){     //do work }finally{     lockInstance.unLock(); }万一程序异常崩了,没执行finally呢?如果程序异常崩了,进程消失后,进程内的资源自然就都释放掉了:续期任务没有了,续期的线程|线程池也没有了。但锁资源就需要依赖锁服务,如 Redis ,在锁过期后主动释放掉锁资源。问题:关于停止任务,在前文独立线程的实现方式中,有介绍可通过中断机制;但是线程池里的任务怎么取消呢?遇事不决问百度,排名第一必有解
  咱得本意是取消一个任务,示例给出的方法是要把线程池关掉。
  问题:取消一个任务,要把整个线程池都关掉?按照示例所给的办法是不行的,每个任务的取消,都要关闭整个线程池的话,若给每个任务都配有独立的取消能力,就需要给每个任务都配一个独立的线程池,这就跟每个锁配一个独立的线程没有区别了。
  问题:目标是多个任务共享一个线程池,怎么不关闭线程池而只关闭特定的任务呢?百度出来跟问题相关的文章本就不多,而多数文章提供的奇思妙招并不好使,笔者是浪费了一些时间的,但不能再耽误读者朋友的时间,直接给思路:解铃还须系铃人,scheduleAtFixedRate的返回值是是ScheduledFuture。
  问题:看到 xxxFuture 是否想能想起Future接口的能力?猜测熟悉 get()方法的同学应该特别多,但不知道熟不熟悉cancel方法,如果看到这个方法感到惊喜,欢迎留言互动。
  public interface Future { boolean cancel(boolean mayInterruptIfRunning); ... V get() throws InterruptedException, ExecutionException; ... } 复制代码问题:cancel方法好使嘛?不看理论看实效果,试试看:public static void testCancel() throws InterruptedException {     ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);      System.out.println(" start : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(() -> {         System.out.println("  work : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     }, 5, 5, TimeUnit.SECONDS);      TimeUnit.SECONDS.sleep(15);     scheduledFuture.cancel(true);     System.out.println("cancel : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     TimeUnit.SECONDS.sleep(30); }效果满足预期,成功取消了。 start : 2022-12-10T19:24:31.508   work : 2022-12-10T19:24:36.538   work : 2022-12-10T19:24:41.539   work : 2022-12-10T19:24:46.541 cancel : 2022-12-10T19:24:46.541 //成功取消问题:cancel 里都做了什么呢?看源码可知,其内有两层核心逻辑:尝试取消正在执行的任务避免任务再被定时执行
  三、新的思考
  问题:cancel的参数mayInterruptIfRunning 是什么意思?
  从父类cancel方法的注释中可以寻找到答案,如果是 true 的话,即代表尝试通过中断的方式来停止任务
  If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
  问题:那就是说也可能抛出 InterruptedException 了?如果是抛出 InterruptedException ,示例中,并未看到程序测试有异常中断,也未看到有异常日志信息。问题:怎么有点玄学了,还能不是interrupt机制?在任务内尝试捕获一下看看:public static void testExceptionCatch() throws InterruptedException {     ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);     ScheduledFuture<?> scheduledFuture = null;     System.out.println(" start : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     try {         scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(() -> {             System.out.println("  work : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));             try {                 TimeUnit.SECONDS.sleep(1);             } catch (InterruptedException e) {                 e.printStackTrace();             }             //throw new RuntimeException("");         }, 5, 5, TimeUnit.SECONDS);     }catch (Exception exp){         exp.printStackTrace();     }     TimeUnit.SECONDS.sleep(15);     scheduledFuture.cancel(true);     System.out.println("cancel : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     TimeUnit.SECONDS.sleep(30); }
  结果中的信息 java.lang.InterruptedException: sleep interrupted 可以明确是任务内的逻辑是可通过中断机制实现的。start : 2022-12-10T20:10:31.248   work : 2022-12-10T20:10:36.276   work : 2022-12-10T20:10:41.272   work : 2022-12-10T20:10:46.277 cancel : 2022-12-10T20:10:46.277 java.lang.InterruptedException: sleep interrupted         at java.lang.Thread.sleep(Native Method)         at java.lang.Thread.sleep(Thread.java:340)         at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)         at com.wushiyii.lock.ScheduleTest.lambda$testExceptionCatch$1(ScheduleTest.java:39)         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)         at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)         at java.lang.Thread.run(Thread.java:748)
  问题:之前实例中取消任务时,外部也无异常信息,线程池内部留着这个异常干嘛了呢?
  直接抛出异常试试看 public static void testExceptionCatch() throws InterruptedException {     ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);     ScheduledFuture<?> scheduledFuture = null;     System.out.println(" start : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     try {         scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(() -> {             System.out.println("  work : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));             throw new RuntimeException("just throw ");             //throw new RuntimeException("");         }, 5, 5, TimeUnit.SECONDS);     }catch (Exception exp){         exp.printStackTrace();     }     TimeUnit.SECONDS.sleep(15);     scheduledFuture.cancel(true);     System.out.println("cancel : " + LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));     TimeUnit.SECONDS.sleep(30); }
  仔细观察能看出,结果变的有意思了,work只执行了一次,前文中的执行结果中work都执行了3次,这里却只执行了一次。 start : 2022-12-10T20:16:53.285   work : 2022-12-10T20:16:58.307 cancel : 2022-12-10T20:17:08.305
  问题:任务内抛出异常能导致定时任务失去定时执行的能力?
  是的,使用scheduleAtFixedRate有以下几个情况必须注意:任务逻辑中未捕获的异常能导致本该定时执行的任务,后续不再执行。任务逻辑中未捕获的异常不会外抛,外部感知不到。任务逻辑中的异常,需在任务逻辑内捕获并记录,否则无处可知。

再见了,行程卡!12月13日0时,通信行程卡服务正式下线。从2020年2月13日上线,到2022年12月13日下线,通信行程卡在绝大多数人的生活中,起着重要作用。有网友觉得这是一个时代的结束,以后独处,是你最好的增值期不知道大家有没有听说过向上社交这个词,最近,我经常看到这个词。原来,我害怕自己不合群,于是去社交,后来我感觉这太压抑了,于是我就放弃了。因为我明白,与其浪费时间去做自己不享受的事情不联系,真的会陌生你一定有过这样的感受想找久未联系的朋友聊聊天,可点开对方的头像,又不知道如何开口。顺手看了看她的朋友圈,发现早已变成一条横线。很多关系都是如此,从开始的无话不谈,到后来的只言片语从带着感恩的心迈入20232022年又悄悄地从人们手中溜走,不管我们是多么地不舍。回想一年来走过的路,心头浮现出两个字感恩。感谢我从今日头条上所学到的所感受的一切美好。感谢今日头条让我的内心在空闲时间感受到今年世界杯决赛有可能是上届世界杯的重演吗随着昨晚克罗地亚点球胜巴西后,克罗地亚这群老将的实力赛前绝对被低估了,从克罗地亚晋级的剧本来看,和上届世界杯如出一辙,就看半决赛能否淘汰阿根廷闯进决赛,看克罗地亚队的韧劲,闯入决赛林姐那个自梳女白衣黑裤独辫子!这是她们的标志。香云纱的衣服料子硬硬的,乌乌的,仿佛是那种柔中带刚的性子,穿在她身上显得非常贴切。因为她们就是那种柔中带刚的女子呀。一张清水脸,一双浑浊的乌目,还有从小米13外观争议看国产设计之殇文邻章自小米13官宣以来,其所采用的立边直屏外观设计语言就引起了不小的争议,新浪科技甚至为此还开设了一个小米13设计像不像iPhone的话题。说来有趣的是,这在个话题下,不少大V和分享E420笔记本键盘进水失灵,更换维修经历今天一用户拿着一台笔记本电脑问能维修吗?我详细询问了用户机器故障,用户描述自己笔记本不小心进水了,导致键盘失灵了,从网上买了键盘,自己不会更换。我说可以维修更换的。谈好价钱之后开始领先科技打造净水爆款,安吉尔以高品质获用户好评随着人们生活水平的不断提升,健康意识的加强,家庭饮用水安全需求也变得愈发重要。据公开数据显示,今年的双11全网净水器品类线上整体销售额高达5。8亿元。在这之中,高端净水专家安吉尔再吴忠至银川城际公交恢复试运营通知尊敬的各位乘客为便于乘客出行,城际公交吴忠至银川从12月9日起恢复试运行。票价8元,暂时仅支持现金及微信支付。班次发车时间及站点(详见下列公交发班时间表)。后期根据客流情况,适时增LCK评选各位置TOP5选手,UZI排名太低了?看到打野排名网友炸锅了最近LCK网友评选出LOL从S3以来各个位置能排名前五的选手,其中只有两名选手没有获得过S赛冠军,其中一个就是UZI。从这个评选的结果来看,LCK选手的总分比LPL强大太过了,如果
后蜀孟昶宠妃花蕊夫人,俘虏后被赵匡胤霸占,留下一首诗传唱千年君王城上竖降旗,妾在深官哪得知?四十万人齐解甲,更无一个是男儿。花蕊夫人,五代后蜀后主孟昶妃,姓费,也有的说姓徐,青城(今四川都江堰市)人。花蕊夫人自幼能文,尤长于诗,加上貌美若仙一国厚着脸面,向我国索要领土不成功,在报纸上公开辱骂前言对于一个国家领土完整的重要性自不必多说,不仅仅是尊严的问题,更关乎国家的发展和命运。我国曾经因为晚清政府闭关锁国的无能统治,导致我国在西方世界飞速发展的时候,落了下乘,因此在面蒙古族的贡献元代派驻唐崖土司是蒙古族后裔吗?前几日,写了蒙古族的贡献兰州杨氏是蒙古族,永登600年鲁土司亦是成吉思汗后裔介绍了鲁土司是蒙古族,在我国的湖北恩施咸丰县有一座唐崖土司城遗址,并且在2015年7月4日,德国波恩举行中国古代告密史把告密变成国家制度,是中国古代一项重大发明。总体来说,告密制度经历了一个由野蛮向文明,由普罗大众向特定群体变化的过程,了解中国古代告密史,有助于我们了解古代社会的变迁。第一个把告密农村快递为什么进村艰难?2001年,我国加入世界贸易组织WTO,我国经济得到了迅速的发展,人们不再满足于传统的购物模式,2011年,马云创造了阿里巴巴,此后,各大网络购物平台如雨后春笋,迅速席卷了全国。在chatGPT辣么火,你却不会注册chatGPT是什么?一款目前超级火的AI对话聊天工具,只是不同于其他的智能聊天机器人那样,他非常的智能。可以回答你的技术问题帮你写代码还能帮你写小说等等,发挥你的想象力,让他干点快递新国标酝酿中!调查市民关注送货上门,快递员担心收入近日,国家邮政局发布关于征求快递服务国家标准(征求意见稿)意见(以下简称新国标征求意见稿)的通知。征求意见稿对包括快递投递次数等均做出明确要求,快递免费送货上门或将有次数限制也成为经济日报携手京东发布数据东部土特产吸睛又吸金数据来源京东消费及产业发展研究院品牌引领农业高质量发展打造知名农业品牌是农业现代化的重要标志。加快农业品牌建设,能够充分发挥农业品牌对乡村振兴农业农村现代化发展的重要作用。特别是在海南大学在生物传感器研究领域取得新进展2022年以来,海南大学食品科学与工程学院创新团队紧扣热带特色资源食品研究方向,在生物发光免疫传感器高效比色传感器等基础研究领域取得新进展。2022年6月21日,食品科学与工程学院发展从社会责任视角看企业算法治理随着互联网信息技术的蓬勃发展,企业运用数据算法算力,可以迅速获知用户的个人信息和消费轨迹,对市场行情做出精准判断。算法技术的应用促进了企业利益增长,但也引发了一系列企业社会责任缺失三年亏超30亿!物美系养活的购物APP多点赴港IPO关联交易超7成,张文中家族实控本文来源时代周报作者梁春富在物美科技赴港IPO无果后,物美系的多点正式开启了上市进程,实控人张文中的资本版图,或将实现有一次扩张。近日,多点数智有限公司(以下简称多点)正式向港交所