线程池详解

一、线程池的优点缓存

(1)下降资源消耗,经过重复利用已建立的线程池减小线程建立和销毁带来的消耗
(2)提升效应速度,当任务来临时,不用等待线程的建立就能当即执行
(3)提升线程的可管理性,线程是稀缺资源,若是无限制的建立,不只会消耗系统资源,还会下降系统的稳定性,线程池能够进行管理,统一分配和监控
总的来讲线程池的主要特色就是:线程复用、控制最大并发数、管理线程

二、建立线程的三个c经常使用方法并发

(1)建立有固定线程数的方法,corePoolSize等于maximumPoolSize
ExecutorService threadPool = Executors.newFixedThreadPool(5);
(2)建立只有一个线程的线程池,corePoolSize等maximumPoolSize而且都等于1
ExecutorService threadPool2 = Executors.newSingleThreadExecutor();
(3)建立一个可缓存线程池,corePoolSize等于0,maximumPoolSize等于Integer.MAX_VALUE
ExecutorService threadPool3 = Executors.newCachedThreadPool();

三、底层建立线程的方法详解
Java底层建立线程池的源码函数

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.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

corePoolSize:线程池中的常驻核心线程数this

maximumPoolSize:线程池中可以容纳的最大线程数线程

keepAliveTime:空余线程的存好时间,当线程池的数量超过code

corePoolSize时,空闲时间达到keepAliveTime时,多余线程就会配销毁直到只剩余到corePoolSize的数量队列

TimeUnit:keepAliveTime的时间单位资源

workQueue:任务队列,当corePoolSize线程没有空闲的时候,不会立刻扩充线程池的线程数,而是先将任务存放到workQueue中get

threadFactory:常见线程池中的线程的线程工厂源码

handler:拒绝策略,当队列满了,且工做线程大于等于maximumPoolSize时,如何来拒绝请求执行的策略,Java中拒绝策略有四种,分别为AbortPolicy,默认拒绝策略,直接抛出
RejectedExecutionException 异常阻止系统正常运行;
DiscardPolicy,默默的丢弃没法处理的任务;DiscardOldestPolicy,丢弃队列中等待最久的任务;CallerRunsPolicy,调用者运行“一种调节机制,该策略就不会抛弃任务,也不会抛出异常,而是将某些任务回退给调用者

四、推荐使用的建立线程池的方式
上面的三种建立的三种线程池的方式,都推荐,推荐自定义线程池,缘由请看源码,源码以下

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

前两种队列使用了LinkedBlockingQueue,而LinkedBlockingQueue从默认构造函数是

public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

它能够存储Integer.MAX_VALUE个任务,若是系统一直提交任务,而系统又处理缓慢容易引起OOM异常
后一个更不用说能够最大线程数能够建立到Integer.MAX_VALUE个线程更容易引起OOM异常,因此才要自定义线程池
五、自定义一个线程池

ExecutorService threadPool4 = new ThreadPoolExecutor(
                5,
                Runtime.getRuntime().availableProcessors()+1,
                3,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(9),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
相关文章
相关标签/搜索