Does @Scheduler start a new thread?

2019-08-10 10:24发布

问题:

I have a Spring application and it has several scheduled methods

It seems Lo4J stop rolling to new file and grow to 10 Gbytes after the application running for a while.

All configuration looks fine, and I only use notepad ++ to open log file(meaning no lock on log file by editor)

So I ponder there might be another thread running in the application. I dong recall any muti-threading implementation in current application.

Then is it possible that the @Scheduled method causes the issue?

回答1:

@Scheduled causes the code to be run in a separate thread, not necessarily new as it might come from a thread pool.

The non rollover of the log file happens because when log4j tries to rename the file for doing the rollover, some application thread is logging to the file at that precise moment.

According to the code of the log4j rolling file implementation RollingFileAppender, when the time to rollover comes (rollOver() method called), an attempt is made to rename the file.

if the file is locked then no rollover occurs, and log4j continues to use the same file, until the next time the rollover policy is triggered and a rename is again attempted.

So the @Scheduled annotations might be contributing to this, but it might not be the only responsible, if there are for example a high volume of requests if it's a web application, etc.

To decrease the likelyhood of rollover failure, try to the change the @Scheduled threads to run at a different moment than when the rollover attempt occurs.

Also decreasing the logging level to ERROR will reduce the likelihood of rollover failure. See also How to find which thread is locking a file.



回答2:

It should use one of the threads that are are allotted by the configuration's thread pool. The thread will be picked up every time one of the scheduled tasks are executed and once the task has finished, the thread will be freed up back into the pool. The amount of logging is dependent on how often the task is run & how many log statements you have. So, unless there is A LOT of logging then it's probably not your issue.

You should use something similar to this in your scheduler configuration to determine pool size. Your pool size should also be determined by the available threads on your machine. Number of cores, threads per core, jvms, etc.

<task:annotation-driven scheduler="taskScheduler"/>
<task:scheduler id="taskScheduler" pool-size="2"/>