Java多线程-线程池ThreadPoolExecutor

为什么要使用线程池?

如果每个请求都创建一个线程去处理,那么服务器的CPU资源很快就会被耗尽,导致宕机。使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

线程池的作用

1)方便控制线程的数量,避免了因无休止的创建线程导致系统崩溃

2)减少了线程创建和消耗的时间

ThreadPoolExecutor创建线程池

示例:

/**
 * 线程池持有者单例
 */
public class MyThreadPoolHolder {
    private static ThreadPoolExecutor executor;

    private MyThreadPoolHolder() {
    }

    public static ThreadPoolExecutor getInstance() {
        if (executor == null) {
            synchronized (MyThreadPoolHolder.class) {
                if (executor == null) {
                    // Java虚拟机可用的CPU数量
                    int availableProcessor = Runtime.getRuntime().availableProcessors();
                    // 核心线程数
                    int corePoolSize = availableProcessor * 2 + 1;
                    // 最大线程数
                    int maxPoolSize = corePoolSize * 2;
                    // 线程存活时间
                    long keepAliveSeconds = 60L;
                    // 线程队列容量
                    int queueCapacity = 1000;
                    // 线程名称前缀
                    String threadNamePrefix = "MyThread - ";
                    // 设置拒绝策略,默认是 ThreadPoolExecutor.AbortPolicy(),丢弃任务并抛出异常
                    RejectedExecutionHandler rejectPolicy = new ThreadPoolExecutor.AbortPolicy();

                    // 使用 ThreadPoolExecutor 创建线程池
                    executor =  new ThreadPoolExecutor(corePoolSize,
                            maxPoolSize,
                            keepAliveSeconds,
                            TimeUnit.SECONDS,
                            new LinkedBlockingDeque<Runnable>(queueCapacity),
                            new MyThreadFactory(threadNamePrefix),
                            rejectPolicy);
                }
            }
        }

        return executor;
    }
}

/**
 * 线程工程类
 */
class MyThreadFactory implements ThreadFactory {
    /**
     * 线程名称前缀
     */
    private String threadNamePrefix;
    /**
     * 线程索引
     */
    private int threadIndex = -1;
    /**
     * 是否守护线程
     */
    private boolean isDaemon;

    public MyThreadFactory(String threadNamePrefix) {
        this.threadNamePrefix = threadNamePrefix;
        this.isDaemon = false;
    }

    public MyThreadFactory(String threadNamePrefix, boolean isDaemon) {
        this.threadNamePrefix = threadNamePrefix;
        this.isDaemon = isDaemon;
    }

    @Override
    public Thread newThread(Runnable target) {
        String threadName;
        synchronized (this) {
            threadIndex++;
            threadName = threadNamePrefix + threadIndex;
        }
        Thread thread = new Thread(target, threadName);
        thread.setDaemon(isDaemon);
        return thread;
    }
}

使用线程池提交不需要返回值的任务

public class Test {
    public static void main(String[] args) {
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
                    System.out.println("r1执行,输出: " + i);
                }
            }
        };

        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
                    System.out.println("r2执行,输出: " + i);
                }
            }
        };
        // 提交任务
        MyThreadPoolHolder.getInstance().execute(r1);
        MyThreadPoolHolder.getInstance().execute(r2);
    }
}

运行结果:

使用线程池提交需要返回值的任务

public class Test {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        Callable<List<String>> task1 = new Callable<List<String>>() {
            @Override
            public List<String> call() throws Exception {
                List<String> list = new ArrayList<>();
                for (int i = 1; i <= 10; i++) {
                    System.out.println("-----task1,运行----");
                    list.add("task1,值:" + i);
                }
                return list;
            }
        };
        Callable<List<String>> task2 = new Callable<List<String>>() {
            @Override
            public List<String> call() throws Exception {
                List<String> list = new ArrayList<>();
                for (int i = 1; i <= 10; i++) {
                    System.out.println("-----task2,运行----");
                    list.add("task2,值:" + i);
                }
                return list;
            }
        };
        // 提交任务
        Future<List<String>> future1 = MyThreadPoolHolder.getInstance().submit(task1);
        Future<List<String>> future2 = MyThreadPoolHolder.getInstance().submit(task2);

        Thread.sleep(3000);
        System.out.println("任务提交之后,就开始运行了,并不是在Future.get()的时候才运行的");
        // 合并结果
        List<String> listRes = new ArrayList<>();
        listRes.addAll(future1.get());
        listRes.addAll(future2.get());

        for (String item : listRes) {
            System.out.println(item);
        }
    }
}

运行结果:

 

原文地址:https://www.cnblogs.com/lkc9/p/12575684.html