欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring scheduled單線程和多線程使用過程中的大坑

 更新時間:2022年01月28日 11:33:41   作者:程序員大佬  
本文主要介紹了spring scheduled單線程和多線程使用過程中的大坑,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

公司在使用定時任務(wù)的時候,使用的是spring scheduled。

代碼如下:

@EnableScheduling
public class TaskFileScheduleService {


? ? @Scheduled(cron="0 */1 * * * ?")
? ? public void task1(){
? ? .......
? ? }
? ??
? ? @Scheduled(cron="0 */1 * * * ?")
? ? public void task2(){
? ? .......
? ? }

某天,接到領(lǐng)導(dǎo)的電話,說生產(chǎn)環(huán)境的定時任務(wù)不跑了,趕緊給看看~
做為一名負(fù)責(zé)人的程序員,趕緊放下手中泡面,遠(yuǎn)程到公司的電腦~
線程卡死這種問題,第一步當(dāng)然是將jvm中的heap dump和thread dump導(dǎo)出來~
經(jīng)過簡單分析,thread dump中某個線程確實一直處理running狀態(tài),heap dump沒啥問題~
thread dump中的問題線程:

"pool-2-thread-43" #368 prio=5 os_prio=0 tid=0x00005587fd54c800 nid=0x1df runnable [0x00007ff7e2056000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at java.net.SocketInputStream.read(SocketInputStream.java:224)
    at ch.ethz.ssh2.transport.ClientServerHello.readLineRN(ClientServerHello.java:30)
    at ch.ethz.ssh2.transport.ClientServerHello.<init>(ClientServerHello.java:67)
    at ch.ethz.ssh2.transport.TransportManager.initialize(TransportManager.java:455)
    at ch.ethz.ssh2.Connection.connect(Connection.java:643)
    - locked <0x000000074539e0e8> (a ch.ethz.ssh2.Connection)
    at ch.ethz.ssh2.Connection.connect(Connection.java:490)
    - locked <0x000000074539e0e8> (a ch.ethz.ssh2.Connection)
    at com.suneee.yige.medicalserver.common.SSHUtils.connect(SSHUtils.java:24)
    at com.suneee.yige.medicalserver.service.TaskFileScheduleService.getConn(TaskFileScheduleService.java:102)
    at com.suneee.yige.medicalserver.service.TaskFileScheduleService.taskInfo(TaskFileScheduleService.java:108)
    at com.suneee.yige.medicalserver.service.TaskFileScheduleService.task(TaskFileScheduleService.java:74)
    at sun.reflect.GeneratedMethodAccessor295.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
    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)

很明顯,ch.ethz.ssh2.Connection.connect這個方法卡死,導(dǎo)致線程一直處于running狀態(tài)。

由于spring scheduled默認(rèn)是所有定時任務(wù)都在一個線程中執(zhí)行??!這是個大坑?。。?br />也就是說定時任務(wù)1一直在執(zhí)行,定時任務(wù)2一直在等待定時任務(wù)1執(zhí)行完成。這就導(dǎo)致了生產(chǎn)上定時任務(wù)全部卡死的現(xiàn)象。

問題已經(jīng)很明確了,要么解決ch.ethz.ssh2.Connection.connect卡死的問題,要么解決spring scheduled單線程處理的問題。

首先,想到的是處理ch.ethz.ssh2.Connection.connect卡死的問題,但是經(jīng)過一番查找,發(fā)現(xiàn)這個ssh的工具包很久沒更更新過了,也沒有設(shè)置例如httpclient的超時時間之類的。這就很難辦了!果斷放棄??!

現(xiàn)在只剩一條路,怎么在任務(wù)1卡死的時候,任務(wù)2可以按他自己的周期執(zhí)行,且任務(wù)1也按照固定周期執(zhí)行,不會因為某次任務(wù)1卡死導(dǎo)致后續(xù)的定時任務(wù)出現(xiàn)問題!

方法一:

添加配置

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
? ? @Override
? ? public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
? ? ? ? taskRegistrar.setScheduler(Executors.newScheduledThreadPool(50));
? ? }
}

這個方法,在程序啟動后,會逐步啟動50個線程,放在線程池中。每個定時任務(wù)會占用1個線程。但是相同的定時任務(wù),執(zhí)行的時候,還是在同一個線程中。
例如,程序啟動,每個定時任務(wù)占用一個線程。任務(wù)1開始執(zhí)行,任務(wù)2也開始執(zhí)行。如果任務(wù)1卡死了,那么下個周期,任務(wù)1還是處理卡死狀態(tài),任務(wù)2可以正常執(zhí)行。也就是說,任務(wù)1某一次卡死了,不會影響其他線程,但是他自己本身這個定時任務(wù)會一直等待上一次任務(wù)執(zhí)行完成!
這種顯然不行!這也是踩過坑才知道的!?。?/p>

方法二(正解):

添加配置:

@Configuration
@EnableAsync
public class ScheduleConfig {

? ? @Bean
? ? public TaskScheduler taskScheduler() {
? ? ? ? ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
? ? ? ? taskScheduler.setPoolSize(50);
? ? ? ? return taskScheduler;
? ? }
}

在方法上添加注解@Async

@EnableScheduling
public class TaskFileScheduleService {


? ? @Async
? ? @Scheduled(cron="0 */1 * * * ?")
? ? public void task1(){
? ? .......
? ? }
? ??
? ? @Async
? ? @Scheduled(cron="0 */1 * * * ?")
? ? public void task2(){
? ? .......
? ? }

這種方法,每次定時任務(wù)啟動的時候,都會創(chuàng)建一個單獨的線程來處理。也就是說同一個定時任務(wù)也會啟動多個線程處理。
例如:任務(wù)1和任務(wù)2一起處理,但是線程1卡死了,任務(wù)2是可以正常執(zhí)行的。且下個周期,任務(wù)1還是會正常執(zhí)行,不會因為上一次卡死了,影響任務(wù)1。
但是任務(wù)1中的卡死線程越來越多,會導(dǎo)致50個線程池占滿,還是會影響到定時任務(wù)。
這時候,可能會幾個月發(fā)生一次~到時候再重啟就行了!

到此這篇關(guān)于spring scheduled單線程和多線程使用過程中的大坑的文章就介紹到這了,更多相關(guān)spring scheduled單線程和多線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中如何給List進(jìn)行排序(這7種方法輕松實現(xiàn))

    Java中如何給List進(jìn)行排序(這7種方法輕松實現(xiàn))

    在Java項目中可能會遇到給出一些條件,將List元素按照給定條件進(jìn)行排序的情況,這篇文章主要給大家介紹了關(guān)于Java中如何給List進(jìn)行排序的相關(guān)資料,通過文中介紹的這7種方法可以輕松實現(xiàn),需要的朋友可以參考下
    2023-10-10
  • springboot啟動的注意事項之不同包下有同樣名字的class類問題

    springboot啟動的注意事項之不同包下有同樣名字的class類問題

    這篇文章主要介紹了springboot啟動的注意事項之不同包下有同樣名字的class類問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Mybatis中BindingException異常的產(chǎn)生原因及解決過程

    Mybatis中BindingException異常的產(chǎn)生原因及解決過程

    BindingException異常是MyBatis框架中自定義的異常,顧名思義指的是綁定出現(xiàn)問題,下面這篇文章主要給大家介紹了關(guān)于MyBatis報錯BindingException異常的產(chǎn)生原因及解決過程,需要的朋友可以參考下
    2023-06-06
  • 解決java.sql.SQLException:The?server?time?zone?value?'?D1ú±ê×?ê±??'?is?unrecognized問題

    解決java.sql.SQLException:The?server?time?zone?value?&apo

    這篇文章主要介紹了解決java.sql.SQLException:The?server?time?zone?value?'?D1ú±ê×?ê±??'?is?unrecognized問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 為何找不到Java 7中的警告

    為何找不到Java 7中的警告

    在本篇文章和里小編給大家整理的是關(guān)于Java 7中的警告的相關(guān)知識點內(nèi)容,有需要的朋友們可以參考下。
    2019-11-11
  • Java中SimpleDateFormat的使用方法

    Java中SimpleDateFormat的使用方法

    這篇文章主要為大家詳細(xì)介紹了Java中SimpleDateFormat的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • 在SpringBoot中無縫整合Dubbo的實現(xiàn)過程

    在SpringBoot中無縫整合Dubbo的實現(xiàn)過程

    微服務(wù)架構(gòu)已經(jīng)成為現(xiàn)代應(yīng)用開發(fā)的熱門趨勢,而Dubbo作為一款強(qiáng)大的分布式服務(wù)框架,與Spring?Boot的結(jié)合是構(gòu)建高性能微服務(wù)應(yīng)用的理想選擇,本文將詳細(xì)介紹如何在SpringBoot中無縫整合Dubbo,需要的朋友可以參考下
    2024-01-01
  • Java中短路運算符與邏輯運算符示例詳解

    Java中短路運算符與邏輯運算符示例詳解

    這篇文章主要給大家介紹了關(guān)于Java中短路運算符與邏輯運算符的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java全面深入探究SpringBoot攔截器與文件上傳

    Java全面深入探究SpringBoot攔截器與文件上傳

    攔截器對使用SpringMvc、Struts的開發(fā)人員來說特別熟悉,因為你只要想去做好一個項目必然會用到它,文件上傳是一個很常見的功能。在項目開發(fā)過程中,我們通常都會使用一些成熟的上傳組件來實現(xiàn)對應(yīng)的功能
    2022-05-05
  • springboot連接redis并動態(tài)切換database的實現(xiàn)方法

    springboot連接redis并動態(tài)切換database的實現(xiàn)方法

    這篇文章主要介紹了springboot連接redis并動態(tài)切換database,本文主為通過修改ConnectionFactory從而達(dá)到動態(tài)切換database的效果,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03

最新評論