线程池的使用以及实现原理

线程池优点

  • 限流
    控制线程总数,根据硬件人为控制使性能达到最优
  • 复用
    减少线程的频繁创建和销毁复用线程
  • 效率
    因为线程可复用任务相应更快

java中的线程池

        Executors.newFixedThreadPool(nThreads);//固定线程数线程池
        Executors.newCachedThreadPool();//有伸缩性线程池,线程60shou后回收
        Executors.newSingleThreadExecutor();//只有一个核心线程的线程池
        Executors.newSingleThreadScheduledExecutor();//定时任务线程池
        Executors.newWorkStealingPool();//fork/join线程池
  • Executors核心构造方法
    public ThreadPoolExecutor(int corePoolSize,//核心线程数
                              int maximumPoolSize,//最大线程数
                              long keepAliveTime,//超时时间
                              TimeUnit unit,//超时时间单位
                              BlockingQueue<Runnable> workQueue,//缓冲队列
                              ThreadFactory threadFactory,//线程工厂
                              RejectedExecutionHandler handler//拒绝策略
 ) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
  • newFixedThreadPool
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, //核心线程数=传入线程数
                                      nThreads,//最大线程数=传入线程数
                                      0L,//超时间=0
                                      TimeUnit.MILLISECONDS,//超时时间单位=秒
                                      new LinkedBlockingQueue<Runnable>()//双向链表阻塞队列
);
    }
  • newCachedThreadPool
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(
                                      0, //核心线程数=0
                                      Integer.MAX_VALUE,//最大线程数=Integer最大值(可当做无限大)
                                      60L, //超时时间=60
                                      TimeUnit.SECONDS,//超时时间单位=秒
                                      new SynchronousQueue<Runnable>()//不存储元素的阻塞队列
);
    }
  • newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 核心线程数=1
                                    1,//最大线程数=1
                                    0L,//超时时间0     
                                    TimeUnit.MILLISECONDS,//超时时间单位:毫秒
                                    new LinkedBlockingQueue<Runnable>()//双向链表阻塞队列
));
    }

执行流程图

image.png

问题

  • 1.不建议使用Executors创建线程池?为什么?
    Executors创建的线程池内置的参数,使开发人员在不用了解线程池各个参数的含义的情况下进行使用.
    在实际生产环境上运行是十分危险的
  • 2.线程池大小的设置?
    CPU 核数:
    IO密集型:每个线程执行时间长,cpu利用率低;可以多设置一些;CPU核数2或者 (线程等待时间+线程CUP时间)/线程CPU时间cup核数
    CUP密集型:cpu核数+1
    -3.线程池预热:
    ThreadPollExecutor.prestartAllCoreThreads()
  • 4 execute()与 submit()的区别
    submit(Callable<T>) 执行待返回值的任务,根据返回值可知任务的执行结果
    submit()不会抛出异常,异常根据Callable返回
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容