Have been working in Java for a year, don’t you still know the use of Java thread pool? (Code details)

Hello, I’m Chenxi. I’m glad you can read it. This article organizes the code cases related to the thread pool. It took a few days to finish this article. I also hope that I have a deeper understanding of the thread pool. Welcome to read and learn. Exchange, share, gain new knowledge, and make progress together!


1. Preface

Thread (English: thread) is the smallest unit that an operating system can perform operation scheduling.

The thread pool is to create several executable threads and put them into a pool (container). When there are tasks to be processed, they will be submitted to the task queue in the thread pool. After processing, the threads will not be destroyed, but will still be in the thread. Waiting for the next task in the pool.

The thread pool can effectively deal with the concurrency problem of multiple threads, avoid the blocking phenomenon caused by a large number of threads occupying system resources with each other, and can effectively reduce the overhead caused by frequent creation and destruction of threads.


The Executors thread factory class can create a total of four types of thread pools, which can be created through Executors.newXXX.

ThreadPoolExecutor provides four constructors

//五个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue)

//六个参数的构造函数-1
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory)

//六个参数的构造函数-2
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler)

//七个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

In Java, the concept of thread pool is the Executor interface, which is specifically implemented as the ThreadPoolExecutor class. Learning the thread pool in Java is the configuration and learning of the parameters of the ThreadPoolExecutor constructor.

int corePoolSize:该线程池中核心线程数最大值

int maximumPoolSize: 该线程池中线程总数最大值

long keepAliveTime:该线程池中非核心线程闲置超时时长

TimeUnit unit:keepAliveTime的单位

BlockingQueue workQueue:该线程池中的任务队列:维护着等待执行的Runnable对象

Insert picture description here
Next, use code cases to truly show the creation process of common thread pools and how to use them. It is better to practice once a thousand times, try! !


2、FixedThreadPool

Reusable thread pool with fixed number of threads

newFixedThreadPool: Create a fixed-length thread pool, which can control the maximum number of threads concurrently, and the excess threads wait in the queue.

    public static ExecutorService newFixedThreadPool(int nThreads) {
    
    
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

Insert picture description here

There is a thread pool with a specified number of threads, a core thread, which has a fixed number of threads, and the response speed is fast.
Insert picture description here

The core thread does not have a timeout mechanism, and the queue size is not limited. The core thread will be recycled unless the thread pool is closed.

/**
 * Created by 辰兮 2020/10/10
 * newFixedThreadPool 创建一个固定长度线程池,可控制线程最大并发数,超出的线程会在队列中等待。
 */
public class NewFixedThreadPool {
    
    
    public static void main(String[] args) {
    
    
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 5; i++)
        {
    
    
            final int index = i;

            //1- 在未来某个时间执行给定的命令。
            // 该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由 Executor 实现决定。
            fixedThreadPool.execute(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    threadRunMethod(index);
                }
            });

            //2- 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
            // 该 Future 的 get 方法在成功完成时将会返回给定的结果
            fixedThreadPool.submit(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    threadRunMethod(index);
                }
            });
        }
        fixedThreadPool.shutdown();
    }

    /**
     *
     * @param index
     */
    private static void threadRunMethod(int index) {
    
    
        try {
    
    
            System.out.println(index);
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

0
0
1
1
2
2
3
3
4
4

Process finished with exit code 0

3、CachedThreadPool

Cacheable thread pool (ps: fast)

CachedThreadPool cache thread pool, only non-core threads, the maximum number of threads is very large (Int.Max(values)), it will add a new thread for each task, there is a timeout mechanism, when the idle thread exceeds 60s If it is not used, it will be recycled. The disadvantage is that the actual memory size of the system is not considered.

    public static ExecutorService newCachedThreadPool() {
    
    
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

newCachedThreadPool: Create a cacheable thread pool. If the length of the thread pool exceeds the processing needs, idle threads can be flexibly recycled. If there is no recyclable, a new thread is created.

/**
 * Created by 辰兮 2020/10/10
 * newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,
 * 若无可回收,则新建线程。线程池的规模不存在限制。
 */
public class NewCachedThreadPool {
    
    
    public static void main(String[] args) {
    
    
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
    
    
            final int index = i;
            try {
    
    
                Thread.sleep(index * 1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }

            //1- 在未来某个时间执行给定的命令。
            // 该命令可能在新的线程、已入池的线程或者正调用的线程中执行,这由 Executor 实现决定。
            cachedThreadPool.execute(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    System.out.println(index);
                }
            });

            //2- 提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。
            // 该 Future 的 get 方法在成功完成时将会返回给定的结果
            cachedThreadPool.submit(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    System.out.println(index);
                }
            });
        }
        cachedThreadPool.shutdown();
    }
}

0
0
1
1
2
2
3
3
4
4

Process finished with exit code 0

4、SingleThreadExecutor

Single-threaded thread pool (ps: relatively slow)

Throw the tasks to the thread one by one in the specified order, all of them are obediently queued for execution, do not process concurrent operations, and will not be recycled. Work efficiency is slow.

public static ExecutorService newSingleThreadExecutor(){
    
    
    return new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}

It will only create a worker thread to process tasks;

The blocking queue used is LinkedBlockingQueue;

/**
 * Created by 辰兮 2020.10.10
 * newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,
 * 保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
 */
public class NewSingleThreadExecutor {
    
    
    public static void main(String[] args) {
    
    

        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
    
    
            final int index = i;
            /*singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        System.out.println("newSingleThreadExecutor: " + index);
                        Thread.sleep(2*1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });*/

            singleThreadExecutor.submit(new Runnable() {
    
    
                @Override
                public void run() {
    
    
                    try {
    
    
                        System.out.println("newSingleThreadExecutor: " + index);
                        Thread.sleep(1*1000);
                    } catch (Exception e) {
    
    
                    	e.printStackTrace();
                    }
                }
            });
        }

        singleThreadExecutor.shutdown();
    }

}
newSingleThreadExecutor: 0
newSingleThreadExecutor: 1
newSingleThreadExecutor: 2
newSingleThreadExecutor: 3
newSingleThreadExecutor: 4

Process finished with exit code 0

5、ScheduledThreadPool

Scheduling thread pool

It is used to handle delayed tasks or timing tasks.

    /**
     * Creates a new {@code ScheduledThreadPoolExecutor} with the
     * given core pool size.
     *
     * @param corePoolSize the number of threads to keep in the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @throws IllegalArgumentException if {@code corePoolSize < 0}
     */
    public ScheduledThreadPoolExecutor(int corePoolSize) {
    
    
        
        super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
              new DelayedWorkQueue());
    }

This thread pool is the only thread pool with delayed execution and periodic repetitive execution. Its core thread pool is fixed, and the number of non-core threads is unlimited, but it will be recycled immediately when it is idle.

/**
 * Created by 辰兮 2020/10/10
 * newScheduledThreadPool 创建一个固定长度线程池,支持定时及周期性任务执行。
 */
public class NewScheduledThreadPool {
    
    
    public static void main(String[] args) {
    
    
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

        //testSchedule(scheduledExecutorService);

        //testScheduleAtFixedRate(scheduledExecutorService);

        testScheduleWithFixedDelay(scheduledExecutorService);

        // 终止线程池
        //scheduledExecutorService.shutdown();
    }

    /**
     *
     * 跟 testScheduleAtFixedRate 非常类似,就是延迟的时间有点区别
     * 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;
     * 也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,
     * 接着在 initialDelay + 2 * period 后执行,依此类推。
     *
     * 如果任务里面执行的时间大于 period 的时间,下一次的任务会推迟执行。
     * 推迟的时间 : 等到上次的任务执行完之后再延迟period 的时间后执行。
     * @param scheduledExecutorService
     */
    private static void testScheduleWithFixedDelay(ScheduledExecutorService scheduledExecutorService) {
    
    
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    System.out.println("延迟2秒,再3秒执行一次");
                    //如果任务里面执行的时间大于 period 的时间,下一次的任务会推迟执行。
                    //本次任务执行完后下次的任务还需要延迟period时间后再执行
                    Thread.sleep(6*1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
        },2,3,TimeUnit.SECONDS);
    }

    /**
     * 创建并执行一个在给定初始延迟后首次启用的定期操作,后续操作具有给定的周期;
     * 也就是将在 initialDelay 后开始执行,然后在 initialDelay+period 后执行,
     * 接着在 initialDelay + 2 * period 后执行,依此类推。
     *
     * 如果任务里面执行的时间大于 period 的时间,下一次的任务会推迟执行。
     * 推迟的时间 : 等到上次的任务执行完就立马执行。
     * @param scheduledExecutorService
     */
    private static void testScheduleAtFixedRate(ScheduledExecutorService scheduledExecutorService) {
    
    
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    System.out.println("延迟2秒,再3秒执行一次");
                    //如果任务里面执行的时间大于 period 的时间,下一次的任务会推迟执行。
                    //如果任务里面执行的时间大于 period 的时间,本次任务执行完后,下次任务立马执行。
                    Thread.sleep(6*1000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }

            }
        },2,3,TimeUnit.SECONDS);
    }

    /**
     * 创建并执行在给定延迟后启用的一次性操作
     * @param scheduledExecutorService
     */
    private static void testSchedule(ScheduledExecutorService scheduledExecutorService) {
    
    
        scheduledExecutorService.schedule(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                System.out.println("delay 3 seconds");
            }
        }, 3, TimeUnit.SECONDS);
    }
}
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
延迟2秒,再3秒执行一次
....

Benefits of thread pool

1. Reduce resource consumption . Reduce the consumption caused by thread creation and destruction by reusing the created threads.

2. Improve response speed . When the task arrives, the task can be executed immediately without waiting for the thread to be created.

3. Improve the manageability of threads . Threads are scarce resources. If they are created unlimitedly, they will not only consume system resources.


Alibaba Java Manual: Why is it not recommended to use Executors to create a thread pool?

Up.
It is not recommended to use Executors to create thread pools, but you can customize thread pool related parameters to create!


It is the first time to organize related knowledge about thread pools. If there is anything wrong, welcome your guidance!


The best investment is to invest in yourself.

Insert picture description here

2020.10.12 May you all go to be in your love!

Guess you like

Origin blog.csdn.net/weixin_45393094/article/details/109037891