Why use thread pools
Is not more threads better?
-
Threads are not only an object in Java, but also a resource of the operating system. Threads take time to create and destroy.Creation time + Destroy time > Execute task time is not a good idea.
-
Java objects occupy stack memory, and operating system threads occupy system memory. According to the jvm specification, a thread defaults to a maximum stack size of 1M, which is allocated from system memory.More threads consume a lot of memory.
-
Operating systems need to switch thread contexts frequently (everyone wants to be run), affecting performance.
Thread pools are introduced to facilitate the control of the number of threads.
Think about time, space and thread switching.
Thread pool principles-concepts
-
Thread pool manager: Used to create and manage thread pools, including creating thread pools, destroying thread pools, and adding new tasks.
-
Work Threads: Threads in the thread pool that are waiting when there are no tasks and can execute tasks in a loop.
-
Task interface: The interface that each task must implement to allow the worker thread to schedule the execution of the task. It mainly defines the entrance of the task, the end work after the task execution is completed, the execution status of the task, and so on.
-
Task queue: Used to store unprocessed tasks.Provides a buffer mechanism.
Thread Pool API - Interface Definition and Implementation Class
type | Name | describe |
---|---|---|
Interface | Executor | The top-level interface that defines the execute method to execute tasks |
Interface | ExecutorService | Inherited Executor interface, expanded Callable, Future, shutdown methods |
Interface | ScheduledExecutorService | Inherited ExecutorService, adding timer task-related methods |
Implementation Class | ThreadPoolExecutor | Basic, standard thread pool implementation |
Implementation Class | ScheduledThreadPoolExecutor | Inherited ThreadPoolExecutor, implemented ScheduledExecutor Service related timer task method |
ScheduledThreadPoolExecutor is arguably the richest implementation class
Thread Pool API - Method Definition
Thread Pool API - Executors Tool Class
Thread Pool Principle-Task executor Procedure
-
Has the number of core threads been reached?Failed to do so, create a worker thread to execute the task.
-
Is the work queue full?If not, store the newly submitted tasks in the work queue.
-
Has the maximum number of thread pools been reached?If not, a new worker thread is created to perform the task.
-
Finally, execute a rejection policy to handle this task.
Special thread pool information
-
Thread pool information: Number of core threads 5, maximum 5, boundless queue, thread lifetime beyond number of core threads: 5 seconds
That is, when the number of core threads equals the maximum number and there is no bounded queue, the number of fixed threads, more than a few tasks are queued for execution.
-
Number of core threads 0, maximum number of Integer.MAX_VALUE, SynchronousQueue queue, thread lifetime beyond number of core threads: 60 seconds
Directly create the number of threads that need to run the task, with a thread lifetime of 60 seconds.
SynchronousQueue Queue
SynchronousQueue is a queue that can contain only one element internally.The thread inserting the element into the queue is blocked until another thread retrieves the element stored in the queue.Similarly, if a thread attempts to get elements and no elements currently exist, the thread will be blocked until the thread inserts elements into the queue.
Calling this class a queue is a bit exaggerated.It's more like a point.
-
Number of core threads 5, maximum number of Integer.MAX_VALUE, DelayedWorkQueue delay queue, thread lifetime beyond number of core threads: 0 seconds
Timed execution thread pool information: 3 seconds after execution, one-time tasks, to point
Same as Executors.newScheduledThreadPool()
-
When shutdown is invoked, no new tasks are received, and the task execution ends. When the thread pool is closed, the appended tasks can no longer be submitted and will be rejected.
threadPoolExecutor.shutdown();
-
When shutdownnow is called, the threads in the queue are no longer executed, the running threads are terminated, and the appended tasks cannot be committed again after the thread pool is closed and will be rejected for execution.
List <Runnable> shutdownNow = threadPoolExecutor.shutdownNow(); returns the terminated thread.
Test code:
public class Demo7 { //Test: Submit 15 tasks that take 3 seconds to execute and see how 2 tasks exceed their size are handled public void testCommon(ThreadPoolExecutor threadPoolExecutor) throws InterruptedException { for (int i = 0 ; i < 15 ; i++){ int finalI = I; threadPoolExecutor.submit(()->{ System.out.println("Start execution, task" + finalI); try { Thread.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("task" + finalI + "Finished running"); }); System.out.println("Task Submitted Successfully"); } // View the number of threads, view the number of queue waits Thread.sleep(5000L); System.out.println("The current number of thread pool threads is:" + threadPoolExecutor.getPoolSize()); System.out.println("The current number of thread pool threads waiting is:" + threadPoolExecutor.getQueue().size()); // Wait 15 seconds to see the number of threads and queues (theoretically, threads that exceed the number of core threads are automatically destroyed) Thread.sleep(15000L); System.out.println("The current number of thread pool threads is:" + threadPoolExecutor.getPoolSize()); System.out.println("The current number of thread pool threads waiting is:" + threadPoolExecutor.getQueue().size()); } /** * 1,Thread pool information: Number of core threads 5, maximum 10, boundless queue, thread lifetime beyond number of core threads: 5 seconds, denial policy specified * * @throws Exception */ private void threadPoolExecutor1() throws Exception{ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,10,5,TimeUnit.SECONDS, new LinkedBlockingQueue<>()); testCommon(threadPoolExecutor); } /** * 2, Thread pool information: Number of core threads 5, maximum 10, queue size 3, thread lifetime beyond number of core threads: 5 seconds, denial policy specified * * @throws Exception */ private void theadPoolExecutor2() throws Exception{ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println("Task rejected"); } }); testCommon(threadPoolExecutor); } /** * 3, Thread pool information: Number of core threads 5, maximum 5, boundless queue, thread lifetime beyond number of core threads: 5 seconds * * @throws Exception */ private void threadPoolExecutor3() throws Exception{ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,5,5,TimeUnit.SECONDS, new LinkedBlockingQueue<>()); testCommon(threadPoolExecutor); } /** * 4, Thread pool information: * Number of core threads 0, maximum number of Integer.MAX_VALUE, SynchronousQueue queue, thread lifetime beyond number of core threads: 60 seconds * * @throws Exception */ private void threadPoolExecutor4() throws Exception{ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0,Integer.MAX_VALUE,60,TimeUnit.SECONDS, new SynchronousQueue<>()); testCommon(threadPoolExecutor); } /** * 5, Timed Execution Thread Pool Information: Execute in 3 seconds, one-time task, execute <br/> * Number of core threads 5, maximum number of Integer.MAX_VALUE, DelayedWorkQueue delay queue, thread lifetime beyond number of core threads: 0 seconds * * @throws Exception */ private void threadPoolExecutor5() throws Exception{ //Same as Executors.newScheduledThreadPool() ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(5); threadPoolExecutor.schedule(()->{ System.out.println("The task was executed and now it is:" + System.currentTimeMillis()); },3000L,TimeUnit.MILLISECONDS); System.out.println("Task submission was successful and now the time is:" + System.currentTimeMillis() + "Number of threads in the current thread pool" + threadPoolExecutor.getPoolSize()); } /** * 6, Timed Execution Thread Pool Information: Fixed number of threads 5, <br/> * Number of core threads 5, maximum number of Integer.MAX_VALUE, DelayedWorkQueue delay queue, thread lifetime beyond number of core threads: 0 seconds * * @throws Exception */ private void threadPoolExecutor6(){ ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(5); threadPoolExecutor.scheduleWithFixedDelay(()->{ System.out.println("The task was executed and now it is:" + System.currentTimeMillis()); },2000L,1000L,TimeUnit.MILLISECONDS); threadPoolExecutor.scheduleAtFixedRate(()->{ System.out.println("The task was executed and now it is:" + System.currentTimeMillis()); },2000L,1000L,TimeUnit.MILLISECONDS); } public static void main(String[] args) throws Exception { Demo7 demo7 = new Demo7(); // demo7.threadPoolExecutor1(); // demo7.theadPoolExecutor2(); // demo7.threadPoolExecutor3(); // demo7.threadPoolExecutor4(); // demo7.threadPoolExecutor5(); // demo7.threadPoolExecutor6(); } }