JUC ThreadPoolExecutor示例

发布时间 2023-04-11 14:06:28作者: 南翔技校毕业后

0、前言

ThreadPoolExecutor类是JDK中的线程池类,继承自Executor, Executor 顾名思义是专门用来处理多线程相关的一个接口,所有线程相关的类都实现了这个接口,里面有一个execute()方法,用来执行线程,线程池主要提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁的额外开销,提高了响应的速度。相关的继承实现类图例如ScheduledThreadPoolExecutor。

在这里插入图片描述

1、方式一

1.1、工具类

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

public class ThreadPoolExecutorUtil {

    public static ThreadPoolExecutor getPoll() {
        return new ThreadPoolExecutor(
                10,
                30,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(50),
                new TheadFactoryName()
        );
    }

}
import org.springframework.stereotype.Component;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class TheadFactoryName implements ThreadFactory {

    private static final AtomicInteger POOL_NUMBER = new AtomicInteger(1);
    private final ThreadGroup group;
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    public TheadFactoryName() {
        this("el-pool");
    }

    private TheadFactoryName(String name) {
        SecurityManager s = System.getSecurityManager();
        group = (s != null) ? s.getThreadGroup() :
                Thread.currentThread().getThreadGroup();
        //此时namePrefix就是 name + 第几个用这个工厂创建线程池的
        this.namePrefix = name +
                POOL_NUMBER.getAndIncrement();
    }

    @Override
    public Thread newThread(Runnable r) {
        //此时线程的名字 就是 namePrefix + -thread- + 这个线程池中第几个执行的线程
        Thread t = new Thread(group, r,
                namePrefix + "-thread-" + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon()) {
            t.setDaemon(false);
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            t.setPriority(Thread.NORM_PRIORITY);
        }
        return t;
    }
}

1.2、应用

import com.zhengx.study.multithread.test5.config.ThreadPoolExecutorUtil;

import java.util.concurrent.ThreadPoolExecutor;

public class TestThread52 {

    public static void main(String[] args) {
        ThreadPoolExecutor poll = ThreadPoolExecutorUtil.getPoll();
        poll.submit(TestThread52::test);
        poll.submit(TestThread52::test2);

        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }

    private static void test() {
        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }

    private static void test2() {
        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }

}

1.3、测试结果

2、方式二

2.1、工具类

import java.util.concurrent.*;

public class ExecutorUtil {

    private static final ExecutorService executorService;

    static {

        //1、创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
        //2、创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        //3、创建单个线程数的线程池,它可以保证先进先出的执行顺序
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        //4、创建一个可以执行延迟任务的线程池
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(10);
        //5、创建一个单线程的可以执行延迟任务的线程池
        ScheduledExecutorService newSingleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
        //6、创建一个抢占式执行的线程池(任务执行顺序不确定)
        ExecutorService newWorkStealingPool = Executors.newWorkStealingPool();

        executorService = Executors.newFixedThreadPool(20);
    }
    
    /**
     * 提交有结果的返回
     */
    public static <T> Future<T> submit(Callable<T> task) {
        return executorService.submit(task);
    }

    /**
     * 提交无结果的返回
     */
    public static void submit(Runnable task) {
        executorService.submit(task);
    }

}

2.2、应用

import com.zhengx.study.multithread.test5.util.ExecutorUtil;

public class TestThread53 {

    public static void main(String[] args) {

        ExecutorUtil.submit(TestThread53::test);
        ExecutorUtil.submit(TestThread53::test2);

        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }

    private static void test() {
        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }

    private static void test2() {
        for (int i = 0; i < 200; i++) {
            System.out.println("线程名称 " + Thread.currentThread().getName() + " === " + i);
        }
    }
}

2.3、测试结果