返回顶部
首页 > 资讯 > 后端开发 > Python >springscheduled单线程和多线程使用过程中的大坑
  • 255
分享到

springscheduled单线程和多线程使用过程中的大坑

2024-04-02 19:04:59 255人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

公司在使用定时任务的时候,使用的是spring scheduled。 代码如下: @EnableScheduling public class TaskFileScheduleSer

公司在使用定时任务的时候,使用的是spring scheduled。

代码如下:

@EnableScheduling
public class TaskFileScheduleService {


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

某天,接到领导的电话,说生产环境的定时任务不跑了,赶紧给看看~
做为一名负责人的程序员,赶紧放下手中泡面,远程到公司的电脑~
线程卡死这种问题,第一步当然是将JVM中的heap dump和thread dump导出来~
经过简单分析,thread dump中某个线程确实一直处理running状态,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这个方法卡死,导致线程一直处于running状态。

由于spring scheduled默认是所有定时任务都在一个线程中执行!!这是个大坑!!!
也就是说定时任务1一直在执行,定时任务2一直在等待定时任务1执行完成。这就导致了生产上定时任务全部卡死的现象。

问题已经很明确了,要么解决ch.ethz.ssh2.Connection.connect卡死的问题,要么解决spring scheduled单线程处理的问题。

首先,想到的是处理ch.ethz.ssh2.Connection.connect卡死的问题,但是经过一番查找,发现这个ssh的工具包很久没更更新过了,也没有设置例如Httpclient的超时时间之类的。这就很难办了!果断放弃!!

现在只剩一条路,怎么在任务1卡死的时候,任务2可以按他自己的周期执行,且任务1也按照固定周期执行,不会因为某次任务1卡死导致后续的定时任务出现问题!

方法一:

添加配置

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

这个方法,在程序启动后,会逐步启动50个线程,放在线程池中。每个定时任务会占用1个线程。但是相同的定时任务,执行的时候,还是在同一个线程中。
例如,程序启动,每个定时任务占用一个线程。任务1开始执行,任务2也开始执行。如果任务1卡死了,那么下个周期,任务1还是处理卡死状态,任务2可以正常执行。也就是说,任务1某一次卡死了,不会影响其他线程,但是他自己本身这个定时任务会一直等待上一次任务执行完成!
这种显然不行!这也是踩过坑才知道的!!!

方法二(正解):

添加配置:

@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(){
    .......
    }

这种方法,每次定时任务启动的时候,都会创建一个单独的线程来处理。也就是说同一个定时任务也会启动多个线程处理。
例如:任务1和任务2一起处理,但是线程1卡死了,任务2是可以正常执行的。且下个周期,任务1还是会正常执行,不会因为上一次卡死了,影响任务1。
但是任务1中的卡死线程越来越多,会导致50个线程池占满,还是会影响到定时任务。
这时候,可能会几个月发生一次~到时候再重启就行了!

到此这篇关于spring scheduled单线程和多线程使用过程中的大坑的文章就介绍到这了,更多相关spring scheduled单线程和多线程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: springscheduled单线程和多线程使用过程中的大坑

本文链接: https://www.lsjlt.com/news/137948.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • springscheduled单线程和多线程使用过程中的大坑
    公司在使用定时任务的时候,使用的是spring scheduled。 代码如下: @EnableScheduling public class TaskFileScheduleSer...
    99+
    2024-04-02
  • spring scheduled单线程和多线程使用的坑怎么解决
    本篇内容介绍了“spring scheduled单线程和多线程使用的坑怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!公司在...
    99+
    2023-06-29
  • Python中多线程和线程池的使用方法
    Python是一种高级编程语言,它在众多编程语言中,拥有极高的人气和使用率。Python中的多线程和线程池是其强大的功能之一,可以让我们更加高效地利用CPU资源,提高程序的运行速度。本篇博客将介绍Py...
    99+
    2023-10-12
    python
  • 怎么解析Redis6中的单线程和多线程模型
    这篇文章的内容主要围绕怎么解析Redis6中的单线程和多线程模型进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!1....
    99+
    2024-04-02
  • python中多进程和多线程的使用方法
    这篇文章主要介绍了python中多进程和多线程的使用方法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。进程和线程进程是系统进行资源分配的最小单位,线程是系统进行调度执行的最小...
    99+
    2023-06-14
  • Python多线程以及多线程中join()的使用方法
    本篇内容主要讲解“Python多线程以及多线程中join()的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python多线程以及多线程中join()的使用方法”吧!Python多线程与...
    99+
    2023-06-20
  • C++ 多线程编程中线程池的应用
    c++++ 多线程编程中使用线程池的好处包括:1)减少线程创建次数;2)负载均衡;3)避免资源争用。例如,通过使用线程池将图像转换任务分配给线程池,可以提高文件转换应用程序的转换速度。 ...
    99+
    2024-05-14
    多线程 线程池 c++ 标准库
  • python多线程线程锁的使用方法
    小编给大家分享一下python多线程线程锁的使用方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!python的数据类型有哪些python的数据类型:1. 数字类...
    99+
    2023-06-14
  • python 多进程和多线程使用详解
    目录进程和线程 Python的多进程 进程池 多进程间的数据通信与共享 Python的多线程 多线程间的数据共享 使用queue队列通信-经典的生产者和消费者模型进程和线程 进程是...
    99+
    2024-04-02
  • C#单线程和多线程端口扫描器详解
    目录一、项目创建以及页面设计(一)项目新建(二)页面设计二、单线程实现端口扫描(一)代码实现(二)运行结果三、多线程实现端口扫描(一)程序实现(二)运行结果四、总结五、参考资料本文为...
    99+
    2024-04-02
  • 什么是多线程?进程和线程的区别是什么?如何使用Java实现多线程?
    文章目录 前言我们为什么要使用线程而不是进程来实现并发编程什么是线程进程和线程的区别如何使用Java实现多线程创建线程1.创建一个继承 Thread 类的线程类2.实现 Runnable 接口匿名内部类方式实现 Runnable ...
    99+
    2023-08-19
    java JavaEE 多线程 进程
  • Python多线程以及多线程中join()的使用方法示例
    Python多线程与多进程中join()方法的效果是相同的。 下面仅以多线程为例: 首先需要明确几个概念: 知识点一: 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流...
    99+
    2024-04-02
  • python 多线程的使用
    在实际编程过程中经常需要把任务包装成多进程或者多线程,多进程和多线程的区别在于多线程是内存共享、变量等共享的,多进程的进程间是独立运行的,所以创建多线程还是多进程取决于不同的需求。python中因为有全局锁的机制,所以在python中多线程...
    99+
    2023-01-31
    多线程 python
  • java中多线程与线程池的基本使用方法
    目录前言继承Thread 实现Runnale接口Callable线程池常见的4种线程池。总结前言 在java中,如果每个请求到达就创建一个新线程,开销是相当大的。在实际使用中,服务器...
    99+
    2024-04-02
  • java中多线程和线程安全是什么
    这篇文章给大家分享的是有关java中多线程和线程安全是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是进程?电脑中时会有很多单独运行的程序,每个程序有一个独立的进程,而进程之间是相互独立存在的。比如下图中...
    99+
    2023-06-25
  • Android的线程、多线程和线程池面试题有哪些
    这篇“Android的线程、多线程和线程池面试题有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Android的线程、多...
    99+
    2023-06-04
  • 如何使用Python中的多线程编程
    如何使用Python中的多线程编程,需要具体代码示例引言:随着计算机技术的不断发展,多核处理器的普及以及大数据时代的到来,多线程编程变得越来越重要。多线程编程可以充分利用计算机的多个核心,加快程序的执行速度,提高系统的响应性能。Python...
    99+
    2023-10-22
    Python多线程编程
  • 如何使用多线程和锁
    本篇内容介绍了“如何使用多线程和锁”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前言你只面向工作学习吗...
    99+
    2024-04-02
  • java 多线程使用PipedOutStream和PipedInputStream
    package test;import java.io.PipedInputStream;import java.io.PipedOutputStream;public class Pipe...
    99+
    2023-06-02
  • 多线程编程中的线程管理策略
    线程管理策略 线程管理策略可以分为两类: 1. 用户级线程管理 协作式线程管理:线程自愿交出控制权,允许其他线程执行。依赖于线程的合作,可能会导致死锁。 抢占式线程管理:操作系统负责调度线程,强制执行时间片,防止死锁。 2. 内核级线...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作