Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the pit used by single-thread and multi-thread in spring scheduled

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "how to solve the pit used by spring scheduled single-threaded and multithreaded". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

The company uses spring scheduled when using scheduled tasks.

The code is as follows:

@ EnableSchedulingpublic class TaskFileScheduleService {@ Scheduled (cron= "0 * / 1 *?") Public void task1 () {. } @ Scheduled (cron= "0 * / 1 *?") Public void task2 () {. }

One day, I received a call from the leader saying that the scheduled tasks in the production environment had stopped running, so I hastened to take a look.

As a programmer in charge, quickly put down the instant noodles and go to the company's computer remotely.

If the thread is stuck, the first step is to export the heap dump and thread dump in jvm.

After a simple analysis, a thread in thread dump does deal with the running state all the time, and there is nothing wrong with heap dump.

Problem thread in 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.ssh3.transport.ClientServerHello.readLineRN (ClientServerHello.java:30)

At ch.ethz.ssh3.transport.ClientServerHello. (ClientServerHello.java:67)

At ch.ethz.ssh3.transport.TransportManager.initialize (TransportManager.java:455)

At ch.ethz.ssh3.Connection.connect (Connection.java:643)

-locked (a ch.ethz.ssh3.Connection)

At ch.ethz.ssh3.Connection.connect (Connection.java:490)

-locked (a ch.ethz.ssh3.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)

Obviously, the ch.ethz.ssh3.Connection.connect method gets stuck, leaving the thread in the running state all the time.

Because spring scheduled defaults to all scheduled tasks being executed in one thread! This is a big pit!

That is to say, timing task 1 has been executing, and timing task 2 has been waiting for timing task 1 to be completed. This leads to the phenomenon that all scheduled tasks are stuck in production.

The problem is clear: either solve the problem of ch.ethz.ssh3.Connection.connect jam or solve the problem of spring scheduled single-threading.

First of all, I came up with the problem of dealing with ch.ethz.ssh3.Connection.Connect, but after some search, I found that the ssh toolkit had not been updated for a long time, nor did it set a timeout such as httpclient. This is very difficult! Give up decisively!

Now there is only one way, how when Task 1 is stuck, Task 2 can be executed according to its own cycle, and Task 1 is also executed according to a fixed cycle, and there will be no problems with subsequent scheduled tasks because of a certain Task 1 stuck!

Method 1:

Add configuration

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

This method, after the program starts, will gradually start 50 threads and put them in the thread pool. Each timed task takes up 1 thread. But the same scheduled task is executed in the same thread.

For example, the program starts and each timed task takes up one thread. Task 1 begins execution, and Task 2 begins execution. If Task 1 is stuck, then Task 1 is still stuck in the next cycle, and Task 2 can be executed normally. In other words, Task 1 once stuck, will not affect other threads, but his own scheduled task will always wait for the completion of the last task!

This obviously doesn't work! I didn't know until I stepped on the pit!

Method 2 (positive solution):

Add configuration:

@ Configuration@EnableAsyncpublic class ScheduleConfig {@ Bean public TaskScheduler taskScheduler () {ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler (); taskScheduler.setPoolSize (50); return taskScheduler;}}

Add a comment @ Async to the method

@ EnableSchedulingpublic class TaskFileScheduleService {@ Async @ Scheduled (cron= "0 * / 1 *?") Public void task1 () {. } @ Async @ Scheduled (cron= "0 * / 1 *?") Public void task2 () {. }

In this way, each time a scheduled task starts, a separate thread is created to handle it. In other words, multiple threads are started for the same scheduled task.

For example: task 1 and task 2 are processed together, but thread 1 is stuck and task 2 can be executed normally. And in the next cycle, Task 1 will still be executed normally, and Task 1 will not be affected because it got stuck last time.

However, there are more and more stuck threads in Task 1, which will fill up 50 thread pools and still affect scheduled tasks.

At this time, it may happen once every few months to restart at that time!

This is the end of the content of "how to solve the pit used by spring scheduled single-threaded and multithreaded". Thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report