Home  >  Article  >  Java  >  How does Java use thread pool? Code.

How does Java use thread pool? Code.

WBOY
WBOYforward
2023-05-08 14:31:071844browse

Core Principle of Java Thread Pool

Everyone who has read the Java thread pool source code knows that the core class in the Java thread pool is ThreadPoolExecutor, and the core construction method in the ThreadPoolExecutor class is to bring There is a constructor method with 7 parameters as shown below.

 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

The meaning of each parameter is as follows.

  • corePoolSize: The number of resident core threads in the thread pool.

  • maximumPoolSize: The thread pool can accommodate the maximum number of threads executing simultaneously. This value is greater than or equal to 1.

  • keepAliveTime: The survival time of excess idle threads. When the space time reaches the keepAliveTime value, the excess threads will be destroyed until only corePoolSize threads are left.

  • unit: unit of keepAliveTime.

  • workQueue: Task queue, tasks that have been submitted but have not yet been executed.

  • threadFactory: Represents the thread factory that generates worker threads in the thread pool. When users create new threads, the default is generally sufficient.

  • handler: Rejection strategy, indicating how to reject the runnable request execution strategy when the thread queue is full and the worker threads are greater than or equal to the maximum display number of the thread pool (maxnumPoolSize).

And Java's thread pool is implemented through the producer-consumer model. The user of the thread pool is the producer, and the thread pool itself is the consumer. .

The core workflow of Java thread pool is shown in the figure below.

How does Java use thread pool? Code.

Hands on Java thread pool

The thread pool we manually implemented is much simpler than Java's own thread pool. We have removed all kinds of complexity The processing method only retains the core principle: users of the thread pool add tasks to the task queue, and the thread pool itself consumes tasks from the task queue and executes tasks.

How does Java use thread pool? Code.

As long as you understand this core principle, the next code will be much simpler. When implementing this simple thread pool, we can dismantle the entire implementation process. The dismantled implementation process is: defining core fields, creating the internal class WorkThread, creating the constructor of the ThreadPool class, and creating the method to execute the task.

Define core fields

First, we create a Java class named ThreadPool and define the following core fields in this class.

  • DEFAULT_WORKQUEUE_SIZE: Static constant, indicating the default blocking queue size.

  • workQueue: Simulates an actual thread pool using a blocking queue to implement the producer-consumer model.

  • workThreads: Simulate the actual thread pool and use the List collection to save the working threads inside the thread pool.

The core code is as follows.

//默认阻塞队列大小
private static final int DEFAULT_WORKQUEUE_SIZE = 5;

//模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
private BlockingQueue<Runnable> workQueue;

//模拟实际的线程池使用List集合保存线程池内部的工作线程
private List<WorkThread> workThreads = new ArrayList<WorkThread>();

Create the internal class WordThread

Create an internal class WorkThread in the ThreadPool class to simulate the worker thread in the thread pool. The main function is to consume tasks in the workQueue and execute the tasks. Since the worker thread needs to continuously obtain tasks from the workQueue, a while (true) loop is used here to continuously try to consume tasks in the queue.

The core code is as follows.

//内部类WorkThread,模拟线程池中的工作线程
//主要的作用就是消费workQueue中的任务,并执行
//由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
class WorkThread extends Thread{
    @Override
    public void run() {
        //不断循环获取队列中的任务
        while (true){
            //当没有任务时,会阻塞
            try {
                Runnable workTask = workQueue.take();
                workTask.run();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Creating the constructor of the ThreadPool class

Here, we create two constructors for the ThreadPool class. In one constructor, the capacity of the thread pool and the blocking queue are passed in, and in the other constructor Only the capacity of the thread pool is passed in.

The core code is as follows.

//在ThreadPool的构造方法中传入线程池的大小和阻塞队列
public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
    this.workQueue = workQueue;
    //创建poolSize个工作线程并将其加入到workThreads集合中
    IntStream.range(0, poolSize).forEach((i) -> {
        WorkThread workThread = new WorkThread();
        workThread.start();
        workThreads.add(workThread);
    });
}

//在ThreadPool的构造方法中传入线程池的大小
public ThreadPool(int poolSize){
    this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
}

Create a method for executing tasks

Create a method for executing tasks in the ThreadPool class execute(). The implementation of the execute() method is relatively simple, which is to add the Runnable task received by the method to in the workQueue queue.

The core code is as follows.

//通过线程池执行任务
public void execute(Runnable task){
    try {
        workQueue.put(task);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Complete source code

Here, we give the complete source code of the manually implemented ThreadPool thread pool, as shown below.

package io.binghe.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 自定义线程池
 */
public class ThreadPool {

    //默认阻塞队列大小
    private static final int DEFAULT_WORKQUEUE_SIZE = 5;

    //模拟实际的线程池使用阻塞队列来实现生产者-消费者模式
    private BlockingQueue<Runnable> workQueue;

    //模拟实际的线程池使用List集合保存线程池内部的工作线程
    private List<WorkThread> workThreads = new ArrayList<WorkThread>();

    //在ThreadPool的构造方法中传入线程池的大小和阻塞队列
    public ThreadPool(int poolSize, BlockingQueue<Runnable> workQueue){
        this.workQueue = workQueue;
        //创建poolSize个工作线程并将其加入到workThreads集合中
        IntStream.range(0, poolSize).forEach((i) -> {
            WorkThread workThread = new WorkThread();
            workThread.start();
            workThreads.add(workThread);
        });
    }

    //在ThreadPool的构造方法中传入线程池的大小
    public ThreadPool(int poolSize){
        this(poolSize, new LinkedBlockingQueue<>(DEFAULT_WORKQUEUE_SIZE));
    }

 //通过线程池执行任务
    public void execute(Runnable task){
        try {
            workQueue.put(task);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //内部类WorkThread,模拟线程池中的工作线程
    //主要的作用就是消费workQueue中的任务,并执行
    //由于工作线程需要不断从workQueue中获取任务,使用了while(true)循环不断尝试消费队列中的任务
    class WorkThread extends Thread{
        @Override
        public void run() {
            //不断循环获取队列中的任务
            while (true){
                //当没有任务时,会阻塞
                try {
                    Runnable workTask = workQueue.take();
                    workTask.run();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Yes, we only used dozens of lines of Java code to implement a minimalist version of the Java thread pool. Yes, the code of this minimalist version of the Java thread pool embodies the Java thread pool. core principles.

Next, let’s test this minimalist version of the Java thread pool.

Writing a test program

The test program is also relatively simple, that is, by calling the constructor of the ThreadPool class in the main() method, passing in the size of the thread pool, and creating an instance of the ThreadPool class. Then the execute() method of the ThreadPool class is called 10 times in a loop, and the task submitted to the thread pool is: Print the name of the current thread--->> Hello ThreadPool.

The overall test code is as follows.

package io.binghe.thread.pool.test;

import io.binghe.thread.pool.ThreadPool;

import java.util.stream.IntStream;

/**
 * @author binghe
 * @version 1.0.0
 * @description 测试自定义线程池
 */
public class ThreadPoolTest {

    public static void main(String[] args){
        ThreadPool threadPool = new ThreadPool(10);
        IntStream.range(0, 10).forEach((i) -> {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "--->> Hello ThreadPool");
            });
        });
    }
}

Next, run the main() method of the ThreadPoolTest class, and the following information will be output.

Thread-0--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-8--->> Hello ThreadPool
Thread-4--->> Hello ThreadPool
Thread-1--->> Hello ThreadPool
Thread-2--->> Hello ThreadPool
Thread-5--->> Hello ThreadPool
Thread-9--->> Hello ThreadPool
Thread-0--->> Hello ThreadPool

The above is the detailed content of How does Java use thread pool? Code.. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete