In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the meaning of Scheduled time scheduling". 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!
Schedule, which can be thought of as a lightweight Quartz, and is much easier to use than Quartz, is a task scheduling plug-in developed by the spring team, which can perform established tasks according to the time period we designed, starting with a serial Schedule design:
Step 1: add the annotation @ EnableScheduling to the custom class and start scheduling. The specific code is as follows
SpringBootApplication@MapperScan ("com.xash.quartzDemo.mapper") @ EnableSwagger2@EnableSchedulingpublic class SpringbootStartApplication {public static void main (String [] args) {SpringApplication.run (SpringbootStartApplication.class, args);}}
Step 2: create a class and inject it into spring, let the class implement SchedulingConfigurer, and rewrite the configureTasks method, so that you can implement a multi-threaded task execution scheme based on multi-task:
The specific code is as follows
Package com.xash.quartzDemo.config;import java.text.SimpleDateFormat;import java.util.Date;import java.util.concurrent.Executors;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Scheduled;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;import org.springframework.stereotype.Component;import com.serotonin.modbus4j.exception.ErrorResponseException;import com.serotonin.modbus4j.exception.ModbusInitException;import com.serotonin.modbus4j.exception.ModbusTransportException Import com.xash.quartzDemo.collection.utils.Modbus4jUtil;@Componentpublic class TaskConfiguration implements SchedulingConfigurer {@ Autowired private Modbus4jUtil Modbus4jUtil; private SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); @ Scheduled (fixedRate=100,initialDelay=10000) public void myTask () throws InterruptedException, ModbusTransportException, ErrorResponseException, ModbusInitException {System.out.println ("current system time 0:" + sdf.format (new Date (); String name=Thread.currentThread () .getName () System.out.println ("current execution thread" + name);} @ Scheduled (fixedDelayString= "${com.test.scheduled}") public void myTask1 () throws InterruptedException {System.out.println ("current system time 1:" + sdf.format (new Date (); String name=Thread.currentThread () .getName (); System.out.println ("current execution thread" + name) } @ Scheduled (cron = "0ram10 *?") / / execute public void myTask2 () throws InterruptedException {System.out.println ("current system time 2:" + sdf.format (new Date (); String name=Thread.currentThread () .getName (); System.out.println ("current execution thread" + name) every 2 seconds / * throw new RuntimeException (Runtime exception); * / @ Override public void configureTasks (ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler (Executors.newScheduledThreadPool (5));} / * @ Override public void configureTasks (ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.setScheduler (taskExecutor ()) } @ Bean (destroyMethod= "shutdown") public Executor taskExecutor () {return Executors.newScheduledThreadPool (15); / / specify thread pool size} * /}
Executors is the top-level interface of Java thread pool. The principle of Java thread pool is analyzed as follows:
ThreadPoolExecutor in JDK1.8 analyzes the dependencies of thread pool objects:
Executor: the object that executes the submitted thread task. This interface provides a way to separate task submission from how each task will run, including thread usage, scheduling, and so on. This interface defines only one execute () method.
ExecutorService
Provide methods for managing terminations such as shutDown () and shutDownNow () for closing the thread pool and methods for determining whether the thread pool is closed, such as isShutdown (), isTerminated ()
Provides methods that can be generated to track the progress of one or more asynchronous tasks, such as invokeAll (), submit (). The return values of these methods are of type Future, which can get the execution result of the thread.
ThreadPoolExecutor member variable
Ctl is a field that controls the running status of the thread pool and the number of valid threads in the thread pool. Ctl is an Integer that contains two parts of information: the high three bits represent the running status of the thread pool (runState) and the low 29 bits represent the number of valid threads in the thread pool (workerCount)
The life cycle of the thread pool, with a total of five states
RUNNING: can accept newly submitted tasks and can also handle tasks in blocking queues
SHUTDOWN: closed state, no longer accept newly submitted tasks, but can continue to work on saved tasks in the blocking queue. When the thread pool is in the RUNNING state, calling the shutdown () method brings the thread pool into that state. (the finalize () method will also call the shutdown () method to enter this state during execution.)
STOP: cannot accept new tasks and does not process tasks in the queue, interrupting threads that are working on tasks. When the thread pool is in the RUNNING or SHUTDOWN state, calling the shutdownNow () method causes the thread pool to enter that state
TIDYING: if all tasks have been terminated, the workerCount (valid threads) is 0, and after the thread pool enters this state, the terminated () method will be called to enter the TERMINATED state.
TERMINATED: enters this state after the terminated () method is executed, and nothing is done in the default terminated () method.
The conditions for entering TERMINATED are as follows:
Thread pool is not in RUNNING state
Thread pool state is not TIDYING state or TERMINATED state
If the thread pool state is SHUTDOWN and workerQueue is empty
WorkerCount is 0
TIDYING status set successfully.
There are three other ways to deal with ctl
RunStateOf: get the running status
WorkerCountOf: get number of active threads
CtlOf: gets the values of running status and number of active threads
ThreadPoolExecutor constructor
The following explains the parameter meaning of the constructor
CorePoolSize: the number of core threads. When a new task is submitted in the execute () method, the following judgment is performed:
A): if there are fewer threads running than corePoolSize, create a new thread to process the task, even if other threads in the thread pool are idle
B): if the number of threads in the thread pool is greater than or equal to corePoolSize and less than maximumPoolSize, the task is added to the workQueue when the workQueue is not full, and a new thread is created to process the task when the workQueue is full
C): if the corePoolSize and maximumPoolSize are the same, the size of the created thread pool is fixed. If a new task is submitted, if the workQueue is not full, put the request into the workQueue and wait for an idle thread to fetch the task from the workQueue and process it.
D): if the number of running threads is greater than or equal to maximumPoolSize, then if the workQueue is full, the task will be processed through the policy specified by handler
Therefore, when the task is submitted, the order of judgment is corePoolSize-> workQueue-> maximumPoolSize.
MaximumPoolSize: maximum number of threads
WorkQueue: waiting queue. When a task is submitted, if the number of threads in the thread pool is greater than or equal to corePoolSize, the task is encapsulated as a Worker object and placed in the waiting queue.
WorkQueue: holds the blocking queue of tasks waiting to be executed. When a new task is submitted to the thread pool, the thread pool will decide how to handle the task according to the number of running threads in the current thread pool. There are mainly the following processing methods:
Direct switching: the common queue for this approach is SynchronousQueue.
Use unbounded queues: generally use the linked list-based blocking queue LinkedBlockingQueue. If you use this approach, the maximum number of threads that can be created in the thread pool is corePoolSize, and maximumPoolSize will not work. When all the core threads in the thread pool are in RUNNING state, a new task submission is placed in the waiting queue.
Use bounded queues: ArrayBlockingQueue is generally used. By using this method, the maximum number of threads in the thread pool can be limited to maximumPoolSize, which can reduce the consumption of resources, but at the same time, it also makes it more difficult for the thread pool to schedule threads, because the capacity of the thread pool and queue are limited, so in order to make the thread pool processing task throughput reach a relatively reasonable range, and want to make thread scheduling relatively simple. And to reduce the resource consumption of the thread pool as much as possible, we need to set these two numbers reasonably.
If you want to reduce the consumption of system resources (including CPU utilization, operating system resource consumption, context switching overhead, etc.), you can set a larger queue capacity and a smaller thread pool capacity, but this will also reduce the throughput of thread processing tasks.
If the submitted task is blocked frequently, consider resetting the capacity of the thread pool by calling the setMaximumPoolSize () method.
If the capacity of the queue is set small, it is usually necessary to set the capacity of the thread pool a little larger, so that the utilization of CPU will be relatively high. However, if the capacity of the thread pool is set too large, the concurrency will increase if the number of tasks submitted is too large, so the scheduling between threads is a problem to be considered. because it is possible to reduce the throughput of processing tasks.
KeepAliveTime: the thread pool maintains the idle time allowed by threads. When the number of threads in the thread pool is greater than corePoolSize, if no new task is submitted at this time, threads outside the core thread will not be destroyed immediately, but will wait until the waiting time exceeds keepAliveTime
ThreadFactory: this is a variable of type ThreadFactory that is used to create a new thread. Executors.defaultThreadFactory () is used by default to create threads. When you use the default ThreadFactory to create a thread, the newly created thread has the same NORM_PRIORITY priority and is not a daemon thread, and the name of the thread is also set.
Handler: this is a variable of type RejectedExecutionHandler that represents the saturation policy of the thread pool. If the blocking queue is full and there are no idle threads, if you continue to submit the task, you need to adopt a strategy to deal with the task. Thread pools provide four strategies:
AbortPolicy: throw an exception directly, which is the default policy
CallerRunsPolicy: use the caller's thread to execute the task
DiscardOldestPolicy: discards the first task in the blocking queue and executes the current task
DiscardPolicy: discarding tasks directly
There is no difference between the core thread and the non-core thread in the thread pool, they are all threads, but some of the threads in the artificial regular thread pool are called core threads.
Process of thread pool
The ThreadPoolExecutor execution execute method is divided into the following four situations.
1) if there are fewer threads currently running than corePoolSize, create a new thread to execute the task (note that performing this step requires a global lock).
2) if the running thread is equal to or more than corePoolSize, the task is added to the BlockingQueue.
3) if the task cannot be added to the BlockingQueue (the queue is full), create a new thread to process the task (note that performing this step requires a global lock).
4) if creating a new thread will cause the currently running thread to exceed the maximumPoolSize, the task will be rejected and call the
The RejectedExecutionHandler.rejectedExecution () method.
The overall design idea for ThreadPoolExecutor to take the above steps is to avoid acquiring global locks as much as possible when executing the execute () method (which would be a serious scalable bottleneck). After ThreadPoolExecutor finishes warm-up, the number of threads currently running is greater than or equal to corePoolSize). Almost all execute () method calls execute step 2, which does not need to acquire a global lock.
Execute () source code analysis
Why can threads in the thread pool be reused?
We know that a thread will be reclaimed by GC after executing the logic in the run () method, so how the thread pool keeps the thread alive and reuses the thread.
Use the Worker class in the thread pool to wrap the Runnable thread tasks added to the thread pool. First, let's analyze the addWorker () method.
The place where the addWorker () method is used in the execute () method is called only when core and non-core threads are added.
AddWorker source code analysis
From the above, we can see that this is a process of adding threads, but we don't see how the thread pool keeps threads from being destroyed so as to achieve reuse.
We can see from addWorker () that the Runnable added to the thread pool is wrapped as a Worker object. Let's take a look at the Worker object to find out why threads in the thread pool can be reused.
Worker source code analysis
The Worker class inherits Runnable, and AbstractQueuedSynchronizer (this class lays the foundation for Java concurrency, which is important, but I haven't delved into it yet)
Look at the run () method, call runWorker, and take itself as a parameter
Looking at runWorker (), the previous addWorker () method finally executes the start () method, which is Worker's run () method, which in turn executes the runWorker () method.
This while is the reason why the thread in the thread pool is not destroyed. In the run method of Worker, if while continues to execute, then Worker, which inherits the Runnable interface, will always execute, and we know that the carrier of the task in the thread pool is Worker. If Worker continues to execute, it means that the carrier can always exist, in exchange for the Runnable task that we added through the execute () method on the carrier.
So how to ensure that the while method is executed all the time
After the first execution of while, task is set to null, so make sure that task=getTask () = null
Looking at getTask (), you can tell from the name that this is a task to get.
Through the comments in the code, we understand how the thread pool works and how to ensure that the thread (Worker) in the thread pool is reused and not destroyed.
The type of thread pool created by Executors:
1. Fixed number of thread pools (newFixedThreadPool)
Creating a FixedThreadPool with a fixed number of threads is suitable for application scenarios where the current number of threads needs to be limited in order to meet the needs of resource management. It is suitable for servers with heavy load.
Executors constructs newFixedThreadPool mode
View the source code
CorePoolSize = maximumPoolSize = initialized parameter
WorkQueue: blocking queues with unbounded queue LinkedBlockingQueue linked list
KeepAliveTime = 0 because the unbounded queue LinkedBlockingQueue is used as the cache queue, when the corePoolSize is full, all the thread tasks added later will be added to the LinkedBlockingQueue, so the maximumPoolSize is meaningless, so there is no need to set idle time
The impact of using unbounded queues, which is why there is a risk in using Eexcutors to create thread pools
1) when the number of threads in the thread pool reaches corePoolSize, the new task will wait in an unbounded queue, so the number of threads in the thread pool will not exceed corePoolSize.
2) maximumPoolSize will be an invalid parameter when using unbounded queues.
3) keepAliveTime will be an invalid parameter when using unbounded queues.
4) due to the use of unbounded queues, the running FixedThreadPool (unexecuted method shutdown () or shutdownNow ()) does not reject the task (the RejectedExecutionHandler.rejectedExecution method is not called).
Code example
Results:
Why the thread name is repeated: this is the principle of the thread pool, because the thread pool will reuse the created thread, when a task Runnable is mounted to a thread in the thread pool, and after the task is executed, another task will continue to be mounted on the thread, so there will be thread name duplication.
Singleton thread pool (newSingleThreadExecutor)
It is suitable for application scenarios where tasks need to be executed sequentially; and no multiple threads are active at any point in time.
Executors constructs newSingleThreadExecutor mode
source code
CorePoolSize = maximumPoolSize = 1 because it is a singleton thread pool, there is a reused thread in the thread pool
WorkQueue: blocking queues with unbounded queue LinkedBlockingQueue linked list
The reasons for keepAliveTime:0 have been explained above.
Code example
Result
There is only one reusable thread, and the execution order of the tasks is the same as the order in which they are added.
Cache thread pool (newCachedThreadPool)
Create a Mini Program that will create new threads as needed, suitable for performing a lot of short-term asynchronous tasks, or a lighter server.
Executors constructs newCachedThreadPool mode
source code
CorePoolSize:0 indicates that there are no core threads in the thread pool, all are non-core threads
MaximumPoolSize: maximum thread pool capacity Integer
KeepAliveTime:60 seconds because there is no core thread, the threads created in the thread pool are all non-core threads, so the idle time is set for 60 seconds. When the non-core thread is not reused after 60 seconds, it will be destroyed. If no thread is submitted to the thread pool, beyond the idle time, there are no non-idle threads in the thread pool, so the thread pool will not consume too much resources.
WorkQueue:SynchronousQueue is a blocking queue that does not store elements. Each put operation must wait for a take operation, otherwise you cannot continue to add elements.
Code example
Result
Timing thread pool (newScheduledThreadPool)
It is mainly used to run tasks after a given delay, or to perform tasks periodically, such as regularly polling the data of tables in the database.
Executors constructs newScheduledThreadPool mode
WorkQeueu:delayWorkQueue, using delay queues as cache queues
Task submission mode
Schedule (Callable callable, long delay, TimeUnit unit)
Callable: submit Callable or Runnable tasks
Delay: delay time
Unit: time level
This method means that it is executed once after the given delay delay time, and the result is returned.
ScheduleAtFixedRate (Runnable command, long initialDelay, long period, TimeUnit unit)
Command: submit Runnable task
InitialDelay: initial delay time
Period: indicates the time period in which consecutive tasks are executed, including the execution time of the task from the beginning of the first task to the start of the second task
Unit: time level
This method starts to execute tasks periodically according to the period interval after initialDelay time.
ScheduleWithFixedDelay (Runnable command,long initialDelay,long delay,TimeUnit unit)
Command: submit Runnable task
InitialDelay: initial delay time
Delay: indicates the delay time the interval between the end of the first task and the start of the second task
Unit: time level
Singleton delay thread pool (newSingleThreadScheduledExecutor)
Executors constructs newSingleThreadScheduledExecutor mode
CorePoolSize: 1 because it is a singleton thread pool, the core thread is 1, and there is only one reused thread in the thread pool
Summary: multithreaded task scheduling can be realized by using sping thread scheduling combined with java thread pool.
This is the end of the content of "what is the meaning of Scheduled time scheduling". Thank you for 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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.