ThreadPoolExecutor线程池

218 阅读1分钟

为什么要使用线程池?

避免因线程切换而造成的性能损耗

构造ThreadPoolExecutor线程池的参数

构造参数1 构造参数2 构造参数3 构造参数4

corePoolSize: 核心线程数
maximumPoolSize: 最大线程数
keepAliveTime: 线程空闲时间
unit: keepAliveTime参数单位
workQueue: 缓存线程任务阻塞队列
threadFactory: 指定创建线程的工厂
handler: 当提交任务数超过maximumPoolSize+workQueue之和时,任务会交给handler来处理,有4个取值:
	1.new ThreadPoolExecutor.CallerRunsPolicy(): 拒绝任务的处理程序,它直接在execute方法的调用线程中运行拒绝任务
	2.new ThreadPoolExecutor.AbortPolicy(): 抛出RejectedExecutionException拒绝任务的处理程序
	3.new ThreadPoolExecutor.DiscardPolicy(): 拒绝任务的处理程序,静默丢弃被拒绝的任务
	4.new ThreadPoolExecutor.DiscardOldestPolicy(): 拒绝任务的处理程序,丢弃最旧的未处理请求,然后重试execute

基本用法

1.定义Runnable或Callable类型的任务
2.创建ThreadPoolExecutor对象
3.将任务放入ThreadPoolExecutor对象中
4.任务运行结束后通过shutdown方法关闭ThreadPoolExecutor对象

代码展示

import java.util.concurrent.TimeUnit;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadLocalTest extends Thread {

    private final String name;

    public ThreadLocalTest(String name) {
        this.name = name;
    }

    @Override
    public void run() {

        System.out.println("Thread: " + name + "执行");

        try {
            sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Thread: " + name + "结束");

    }

    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 4, 200, TimeUnit.MICROSECONDS, new ArrayBlockingQueue<>(10));

        for (int i = 0; i < 10; i++) threadPoolExecutor.execute(new ThreadLocalTest(String.valueOf(i)));

        threadPoolExecutor.shutdown();

    }
}

打印展示

ThreadPoolExecutor线程池执行器

ThreadPoolExecutor线程池工作方式

1.创建线程池后,线程会随着任务到来的到来而创建
2.线程池中的任务数超出corePoolSize,workQueue队列未满,就会将任务放入到workQueue队列中
3.线程池中的任务数超出corePoolSize,workQueue队列已满,且线程池中的任务数小于maximumPoolSize,会创建maximumPoolSize减corePoolSize再减workQueue个新线程来处理被添加的任务
4.workQueue队列若无界,任务会一直丢到队列中,会导致OutOfMemoryError异常

代码展示

import java.util.concurrent.TimeUnit;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

public class ThreadLocalTest implements Runnable {

    @Override
    public void run() {
        
    }

    public static void main(String[] args) {

        /* 未超出核心线程数 */
        extracted(4);

        /* 超出核心线程数 */
        extracted(8);

        /* 超出缓存线程队列 */
        extracted(12);

    }

    private static void extracted(int size) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 200,
                TimeUnit.MICROSECONDS, new ArrayBlockingQueue<>(5));

        for (int i = 0; i < size; i++) {

            threadPoolExecutor.execute(new ThreadLocalTest());

            System.out.println("线程池任务数量: " + threadPoolExecutor.getPoolSize() + " 队列任务数量: " +
                    threadPoolExecutor.getQueue().size() + " 已完成任务数量: " + threadPoolExecutor.getCompletedTaskCount());

        }

        System.out.println("-----分隔线-----");

        threadPoolExecutor.shutdown();

    }
}

打印展示

ThreadPoolExecutor线程池工作方式