Before learning to timing task thread pool (ScheduledThreadPoolExecutor) found that it mainly depends on the thread pool and its static inner class DelayedWorkQueue implementation. The DelayedWorkQueue is a DelayedWorkQueue. The DelayedWorkQueue is a DelayedWorkQueue.
Delay queue Description
Deferred queues provide the ability to retrieve queue elements at a specified point in time, with the first element in the queue being the element with the highest priority of execution.
It may be easier to understand this by enumerating some usage scenarios, such as the design of the cache system, in which objects in the cache are specified to expire and need to be removed from the cache when they expire; In a task scheduling system, for example, the task should be executed at the exact time specified by the task. In these scenarios, if we did not use deferred queues, we would have to iterate over all caches and tasks differently and then decide whether to remove the cache and execute the task.
The delay queue does not need to keep scanning cache, task, it can achieve can achieve at the exact point in time to execute the task.
Next we comb the realization of the cache removal on time, first of all, we know that each cache expiration time, each cache expiration time stamp can be calculated, we first according to the overdue time stamp for comparison in the priority queue (on an article to introduce the priority queue), and then from a priority queue cache, affirmation is to get the first need to cache expiration, Determine whether the cache has reached the expiration time, if not, the thread is blocked (the difference between the expiration time and the current time stamp), after a certain time, the thread will automatically wake up, and verify again to find that the cache just expired, you can remove the cache.
Similarly, the execution of scheduled tasks on time is the same, but the expiration of the cache timestamp is replaced by the next execution of scheduled tasks as a comparison.
Analysis shows that to implement this functionality, a priority queue is required, and the stored element specifies the time stamp for removing the queue.
This section describes the DelayQueue property
From the previous analysis, it can be concluded that the DelayQueue must have the function of a priority queue, and the stored elements must have a certain time to remove the queue, so we look at the concrete implementation of DelayQueue, the basic attribute source code is shown in the following figure:
You can see that it uses the priority queue Q to store data, so it has all the functionality of a priority queue.
With respect to Delayed, all elements it can store must inherit from the Comparable interface. The Delayed source code declares the method “Long getDelay(TimeUnit unit);” Returns the remaining delay associated with this object in a given unit of time. It can directly calculate the remaining latency of the object, like the remaining time of the cache, and then perform the thread blocking time of the object acquired.
The Delayed object then has both the implementation of Comparable required by the priority queue and the time remaining for the Delayed object to execute.
DelayQueue key implementation
Take a look directly at the implementation of the method, source code as follows:
Once you understand priority queues in the last article, it’s easy to look at the code for delay queues. The priority queue is used to retrieve elements, and the getDelay (declared by the Delayed interface) method is called to determine if it is blocked and for how long.
If the leader thread is not null, it will block directly. The leader thread can wake up after the leader thread finishes executing. When will the leader thread wake up?
The leader blocks indefinitely because there is no data in the queue, so it must be the place to add data. After the offer method saves the element successfully, it checks whether the first element in the queue is the one that was just saved, and if so, it calls available.signal(). Wake up the thread, the code is relatively simple not to post.
Best practices for deferred queuing
Delays in the queue to say best practices will say the timing task submitted to the front, timing task thread pool ScheduledThreadPoolExecutor mentioned in the previous analysis, so we direct the implementation of ScheduledThreadPoolExecutor, key source code is as follows:
Before each task is put into the task queue, the next execution time will be set. As shown in the figure above, getDelay and compareTo methods are implemented through time, so that a thread pool can save multiple scheduled tasks, and each task will reset the time after execution and then continue to be put into the priority queue of the thread pool. That’s how simple it is to implement a timed task.
conclusion
After understanding the priority queue, it is very simple to look at the delay queue. It is nothing more than extending a little function on the basis of the priority queue. How to implement the timing task is very simple.
Java programmer daily study notes, such as understanding the wrong welcome to exchange discussion!