0.9.1、自定义线程池

描述

自定义线程池可以帮助我们掌握更多的线程自主权,方便于后期代码的维护和问题的排查。

应用知识点

  • 自定义线程池
  • 线程工厂
  • 线程池关闭
  • 线程池最佳线程数
在《Java Concurrency in Practice》一书中,给出了估算线程池大小的公式:
  Nthreads = Ncpu x Ucpu x (1 + W/C),其中
  Ncpu = CPU核心数
  Ucpu = CPU使用率,0~1
  W/C = 等待时间与计算时间的比率
public static void main(String [] args){
        int CPU_numbers = Runtime.getRuntime().availableProcessors();
        System.out.println("CPU_numbers="+CPU_numbers);
    }

线程池拒绝策略

四种策略
使用CallerRunsPolicy【主线程参与任务执行】
DiscardOldestPolicy【FIFO】
DiscardPolicy【丢弃没异常】
AbortPolicy【丢弃抛异常】

默认策略
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();

代码

Maven
<dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>29.0-jre</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.72</version>
    </dependency>
自定义 Java 线程池
  • 支持 自定义线程工厂 namedThreadFactory
  • 支持获取线程执行结果 newFutureTask
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 * @Title: 线程池测试
 * @Description: 线程池测试
 * @Author: wujie
 * @Version: v1.0
 * @Date:2020-06-10
 * @Updatedby:
 */
public class ThreadTest {
    private final static int CORE_POOL_SIZE = 10;
    private final static int MAX_I_MUM_POOL_SIZE = 10;
    private final static long KEEP_ALIVE_TIME = 0L;
    private final static int WORKQUEUE_SIZE = 1024;
    /**
     * 自定义线程名称,方便的出错的时候溯源
     */
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("center-pool-%d").build();
    private static ExecutorService threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_I_MUM_POOL_SIZE, KEEP_ALIVE_TIME,
            TimeUnit.MILLISECONDS, new LinkedBlockingDeque(WORKQUEUE_SIZE), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());

    /**
     * 获取线程池
     */
    public static ExecutorService getThreadPool() {
        return threadPool;
    }

    /**
     * 获取线程池工厂
     */
    public static ThreadFactory getThreadFactory(){
        return namedThreadFactory;
    }

    /**
     * 执行任务
     * @param r
     */
    public static void newTask(Runnable r) {
        threadPool.execute(r);
    }

    /**
     * 执行任务-需要获取线程执行结果
     * @param r
     */
    public static Future newFutureTask(Runnable r) {
        return threadPool.submit(r);
    }

    /**
     * 关闭线程池(如有在执行任务则等待)
     */
    public static void destroyExecutorService(){
        System.out.println("关闭线程池");
        if(!threadPool.isShutdown()){
            threadPool.shutdown();
        }
    }

    /**
     * 立即关闭线程池
     */
    public static void destroyNowExecutorService(){
        System.out.println("立即关闭线程池");
        if(!threadPool.isShutdown()){
            threadPool.shutdownNow();
        }
    }

    /**
     * 线程池是否关闭
     * @return
     */
    public static boolean isExecutorServiceDownNow(){
        return threadPool.isShutdown();
    }
}
自定义线程池的简单使用
自定义线程池结合 Thread
public class ThreadUseTest {

    private static class MyThread extends Thread{
        @Override
        public void run() {
            super.run();
            System.out.println("自定义线程池,可以通过构造参数传参");
        }
    }

    public static void main(String [] args){
        ThreadTest.newTask(ThreadTest.getThreadFactory().newThread(new MyThread()));
        ThreadTest.destroyExecutorService();
    }
}
自定义线程池结合 Runnable
public class ThreadUseTest {

    private static class MyRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("自定义线程池,可以通过构造参数传参");
        }
    }

    public static void main(String [] args){
        ThreadTest.newTask(ThreadTest.getThreadFactory().newThread(new MyRunnable()));
        ThreadTest.destroyExecutorService();
    }
}

自定义线程池结合 Future (需要获取执行结果)

Futuretask 学习(如果了解 Future 可以直接看 “使用线程池执行 FutureTask”小标题,否则建议阅读全文)

参考资料

[1]、https://www.cnblogs.com/xhq1024/p/12125290.html

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页