The start and end of each thread consumes time and resources.
If a lot of threads are used in the system, a large number of start and end actions will cause the performance of the system to change card and slow down the response.
In order to solve this problem, the thread pool is introduced.
The pattern of thread pool is very similar to the producer consumer model, and the consumption objects are tasks that can be run one by one
The idea of thread pool
The idea of thread pool is very close to the producer consumer model.
- Prepare a task container
- Start 10 consumer threads at a time
- At first, the task container is empty, so the threads are wait ing on it.
- Until an external thread throws a "task" into the task container, a consumer thread will be awakened to notify
- The consumer thread takes out the "task" and executes the task. After execution, it continues to wait for the next task.
- If more tasks are added in a short period of time, multiple threads will be awakened to execute these tasks.
In the whole process, there is no need to create new threads, but to recycle the existing threads
Develop a custom thread pool
package multiplethread; import java.util.LinkedList; public class ThreadPool { // Thread pool size int threadPoolSize; // Task container LinkedList<Runnable> tasks = new LinkedList<Runnable>(); // Thread trying to consume task public ThreadPool() { threadPoolSize = 10; // Start 10 task consumer threads synchronized (tasks) { for (int i = 0; i < threadPoolSize; i++) { new TaskConsumeThread("Task consumer thread " + i).start(); } } } public void add(Runnable r) { synchronized (tasks) { tasks.add(r); // Wake up the waiting task consumer thread tasks.notifyAll(); } } class TaskConsumeThread extends Thread { public TaskConsumeThread(String name) { super(name); } Runnable task; public void run() { System.out.println("Start up: " + this.getName()); while (true) { synchronized (tasks) { while (tasks.isEmpty()) { try { tasks.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } task = tasks.removeLast(); // Threads that allow tasks to be added can continue to add tasks tasks.notifyAll(); } System.out.println(this.getName() + " Get the task and execute it"); task.run(); } } } }
Test thread pool
Create a scenario where each task takes one second to execute
The first step is to add tasks to the thread pool every 1 second
Then the interval is getting shorter and shorter. Before the thread executing the task can finish, new tasks come again. You will see other threads in the thread pool wake up to perform these tasks.
package multiplethread; public class TestThread { public static void main(String[] args) { ThreadPool pool= new ThreadPool(); int sleep=1000; while(true){ pool.add(new Runnable(){ @Override public void run() { //System.out.println (the "execution of the task"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); try { Thread.sleep(sleep); sleep = sleep>100?sleep-100:sleep; } catch (InterruptedException e) { e.printStackTrace(); } } } }
Using java's own thread pool
java provides its own thread pool instead of developing a custom thread pool.
Thread pool class ThreadPoolExecutor java.util.concurrent lower
ThreadPoolExecutor threadPool= new ThreadPoolExecutor(10, 15, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
The first parameter 10 indicates that the thread pool initializes 10 threads to work in it
The second parameter, 15, automatically increases to a maximum of 15 threads if 10 threads are insufficient
The third parameter 60 combines with the fourth parameter TimeUnit.SECONDS , which means that after 60 seconds, the extra threads will be recycled before receiving the work. Finally, there are only 10 threads in the pool
Fourth parameter TimeUnit.SECONDS As above
The fifth parameter, new LinkedBlockingQueue(), is used to put the collection of tasks
The execute method is used to add a new task
package multiplethread; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class TestThread { public static void main(String[] args) throws InterruptedException { ThreadPoolExecutor threadPool= new ThreadPoolExecutor(10, 15, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); //The execute method is used to add a new task threadPool.execute(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub System.out.println("Task 1"); } }); } }