多线程-线程池

Posted wanthune

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程-线程池相关的知识,希望对你有一定的参考价值。

Executors

  1. Executors.newFixedThreadPool(int):创建一个固定线程数的线程池,其最大线程数跟核心线程数一样大。使用LinkBlockingQueue.
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
  1. Executors.newCachedThreadPool():保证每次请求都有线程执行,故每次的请求,如果没有线程空闲,则直接创建一个新的线程去执行,最大线程数是Integer.MAX_VALUE,在60s内没有新任务,则销毁。使用的是SynchronousQueue.
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
  1. Executors.newSingleThreadExecutor():单线程,
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

4.Executors.newScheduledThreadPool(int corePoolSize):创建一个线程池,该线程池可以安排命令在给定延迟后运行或定期执行

 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
// 其父类为ThreadPoolExecutor
 public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
  1. ThreadPoolExecutor 的构造方法:
//corePoolSize 核心线程数,maximumPoolSize 最大线程数,keepAliveTime:当线程数大于核心时,这是多余空闲线程在终止之前等待新任务的最长时间 ,unit:keepAliveTime的时间单位,workQueue:使用的队列,在执行任务之前用于保存任务的队列。此队列将仅包含由{@code execute}方法提交的{@code Runnable}任务。
 public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) 

  1. BlockingQueue:
    ArrayBlockingQueue:数组阻塞队列,一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素

DelayQueue:Delayed 元素的一个无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且 poll 将返回 null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时,将发生到期。即使无法使用 take 或 poll 移除未到期的元素,也不会将这些元素作为正常元素对待。例如,size 方法同时返回到期和未到期元素的计数。此队列不允许使用 null 元素

LinkedBlockingDeque:一个基于已链接节点的、任选范围的阻塞双端队列。可选的容量范围构造方法参数是一种防止过度膨胀的方式。如果未指定容量,那么容量将等于 Integer.MAX_VALUE。只要插入元素不会使双端队列超出容量,每次插入后都将动态地创建链接节点。大多数操作都以固定时间运行(不计阻塞消耗的时间)。异常包括 remove、removeFirstOccurrence、removeLastOccurrence、contains、iterator.remove() 以及批量操作,它们均以线性时间运行。

LinkedBlockingQueue:链阻塞队列,LinkedBlockingQueue 类实现了 BlockingQueue 接口。LinkedBlockingQueue 内部以一个链式结构(链接节点)对其元素进行存储。如果需要的话,这一链式结构可以选择一个上限。如果没有定义上限,将使用 Integer.MAX_VALUE 作为上限。LinkedBlockingQueue 内部以 FIFO(先进先出)的顺序对元素进行存储。队列中的头元素在所有元素之中是放入时间最久的那个,而尾元素则是最短的那个。

LinkedTransferQueue:参考:https://blog.csdn.net/qq_39470742/article/details/90172745

PriorityBlockingQueue:一个无界阻塞队列,它使用与类 PriorityQueue 相同的顺序规则,并且提供了阻塞获取操作。虽然此队列逻辑上是无界的,但是资源被耗尽时试图执行 add 操作也将失败(导致OutOfMemoryError)。此类不允许使用 null 元素。依赖自然顺序的优先级队列也不允许插入不可比较的对象(这样做会导致抛出 ClassCastException)。此类及其迭代器可以实现 Collection 和 Iterator 接口的所有可选 方法。iterator() 方法中提供的迭代器并不 保证以特定的顺序遍历 PriorityBlockingQueue 的元素。如果需要有序地进行遍历,则应考虑使用 Arrays.sort(pq.toArray())。此外,可以使用方法 drainTo 按优先级顺序移除 全部或部分元素,并将它们放在另一个 collection 中。在此类上进行的操作不保证具有同等优先级的元素的顺序。如果需要实施某一排序,那么可以定义自定义类或者比较器,比较器可使用修改键断开主优先级值之间的联系。例如,以下是应用先进先出 (first-in-first-out) 规则断开可比较元素之间联系的一个类。要使用该类,则需要插入一个新的 FIFOEntry(anEntry) 来替换普通的条目对象。

SynchronousQueue:是一个特殊的队列,它的内部同时只能够容纳单个元素。如果该队列已有一元素的话,试图向队列中插入一个新元素的线程将会阻塞,直到另一个线程将该元素从队列中抽走。同样,如果该队列为空,试图向队列中抽取一个元素的线程将会阻塞,直到另一个线程向队列中插入了一条新的元素。


以上是关于多线程-线程池的主要内容,如果未能解决你的问题,请参考以下文章

线程池

多线程编程

多线程线程池

多线程线程池

多线程线程池

Java多线程-线程池的使用与线程总结(狂神说含代码)