自定义线程池,如何最佳创建线程池

java有预置线程池:newSingleThreadExecutor,newFixedThreadPool,newCacheedThreadPool,newScheduledThreadPool,newWorkStealingPool。如果不适合,还可以使用ThreadPoolExecutor创建自定义线程池。主要构造方法:

 1 public ThreadPoolExecutor(int corePoolSize,
 2                           int maximumPoolSize,
 3                           long keepAliveTime,
 4                           TimeUnit unit,
 5                           BlockingQueue<Runnable> workQueue)
 6
 7 public ThreadPoolExecutor(int corePoolSize,
 8                           int maximumPoolSize,
 9                           long keepAliveTime,
10                           TimeUnit unit,
11                           BlockingQueue<Runnable> workQueue,
12                           ThreadFactory threadFactory,
13                           RejectedExecutionHandler handler)

我们接下来介绍参数,其中线程池大小与前四个参数有关。

  • corePoolSize: 核心线程数。

    • 刚创建线程池,没有,即不会预先创建。当任务到来,且当前线程没有超过corePoolSize,就会创建一个新线程执行该任务,即使其他线程是空闲。
    • 不会因为空闲而被释放,keepAliveTime不适用。
  • maximumPoolSize:最大线程数。如上面情况,如果当前线程超过corePoolSize,先尝试排队,如果队列满了或者其他情况不能入队,那么它不会排队,而是检查线程数是否达到maximumPoolSize,如果没有,就创建线程,直到线程数达到maximumPoolSize。
  • keepAliveTime:空闲线程存活时间。当线程池的线程数大于corePoolSize,额外空闲线程的存活时间。如果到了时间,还没有新任务,就会释放线程。值为0,表示线程不会超时释放。
  • unit
  • BlockingQueue:阻塞队列。可以使用LinkedBlockingQueue(默认无界)、ArrayBlockingQueue、PriorityBlockingQueue(无界)、SynchronousQueue(没实际存储空间)。使用无界队列,需要注意,线程数最多达到corePoolSize,新任务来只能排队,maximumPoolSize没意义。SynchronousQueue只有正好有空闲线程,才会入队成功,否则总是创建新线程,直到达到maximumPoolSize。
  • handler:任务拒绝策略。有界队列,线程数达到maximumPoolSize,队列满了,触发任务拒绝策略。四种处理方式:AbortPolicy(默认,抛出异常),DiscardPolicy(忽略新任务,不抛异常),DiscardOldestPolicy(扔掉等待时间最长,自己排队),CallerRunsPolicy(任务提交者线程执行任务)

最佳自定义创建线程池,队列有界,maximumPoolSize有限,使用任务拒绝策略。如果队列无界,服务不了的任务总是会排队,消耗内存,甚至引发内存不足异常。如果队列有界但maximumPoolSize无线,可能会创建过多线程,占内存和CPU。

原文地址:https://www.cnblogs.com/ivy-xu/p/12607811.html

时间: 2024-08-30 08:28:39

自定义线程池,如何最佳创建线程池的相关文章

使用线程池而不是创建线程

在我们开发程序时,若存在耗性能.高并发处理的任务时,我们会想到用多线程来处理.在多线程处理中,有手工创建线程与线程池2种处理方式,手工创建线程存在管理与维护的繁琐..Net线程池能够帮我们完成线程资源的管理工作,使用我们专注业务处理,而不是代码的细微实现.在你创建了过多的任务,线程池也能用列队把无法即使处理的请求保存起来,直至有线程释放出来. 当应用程序开始执行重复的后台任务,且并不需要经常与这些任务交互时,使用.Net线程池管理这些资源将会让性能更佳.我们可以使用ThreadPool.Queu

linux线程笔记1之创建线程

1 线程与进程的对比 这里有一个笔记详细的阐述 http://blog.csdn.net/laviolette/article/details/51506953 2 创建线程函数 int pthread_create(pthread_t *thread, const pthread_attr_t *attr,                          void *(*start_routine) (void *), void *arg); 参数意义: typedef unsigned l

线程的基本操作,创建线程,结束线程,新线程跟原线程共享变量

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h> // 包含线程库 #include <string.h> void *thread_function(void *arg); // 定义线程函数原型 //char message[] = "THREAD_TEST"; // 定义公用的内存空间 char message[

Android性能优化之线程池策略和对线程池的了解

线程的运行机制 1. 开启线程过多,会消耗cpu 2. 单核cpu,同一时刻只能处理一个线程,多核cpu同一时刻可以处理多个线程 3. 操作系统为每个运行线程安排一定的CPU时间----`时间片`,系统通过一种循环的方式为线程提供时间片,线程在自己的时间内运行,因为时间相当短,多个线程频繁地发生切换,因此给用户的感觉就是好像多个线程同时运行一样,但是如果计算机有多个CPU,线程就能真正意义上的同时运行了. 线程池的作用 1. 线程池是预先创建线程的一种技术.线程池在还没有任务到来之前,创建一定数

线程池;java实现线程池原理

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中.如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙.如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程可以排队,但他们要等到其他线程完成后才启动. 组成部分 1.线程池

线程池;java的线程池的实现原理;适用于频繁互动(如电商网站)

线程池是一种多线程处理形式,处理过程中将任务加入到队列,然后在创建线程后自己主动启动这些任务.线程池线程都是后台线程.每一个线程都使用默认的堆栈大小,以默认的优先级执行.并处于多线程单元中. 假设某个线程在托管代码中空暇(如正在等待某个事件),则线程池将插入还有一个辅助线程来使全部处理器保持繁忙. 假设全部线程池线程都始终保持繁忙,但队列中包括挂起的工作,则线程池将在一段时间后创建还有一个辅助线程但线程的数目永远不会超过最大值.超过最大值的线程能够排队,但他们要等到其它线程完毕后才启动. 组成部

C#线程篇---你所不知道的线程池(4)

线程的创建和销毁都要耗费大量的时间,有什么更好的办法?用线程池! 太多的线程浪费内存资源,有什么更好的办法?用线程池! 太多线程有损性能,有什么更好的办法?用线程池!(⊙_⊙)? 线程池是什么?继前三篇线程基础之后,我们要来学学线程池了.注意,这些信息相当有用! 为了设计和实现可伸缩的.可响应的和可靠的应用程序或组建,线程池是你必须采用的核心技术. 线程池是CLR的,线程池自动为你管理线程的创建和销毁,线程池创建的一组线程将为各种任务而重用,极大提高了使用线程的成本,这也就意味着,你的应用程序其

驱动开发之 创建线程函数PsCreateSystemThread

PsCreateSystemThread 创建一个执行在内核模式的系统线程. 注意:创建线程必须用函数PsTerminateSystemThread强制线程结束.否则该线程是无法自动退出的. 函数原型: [cpp] view plain copy print? NTSTATUS PsCreateSystemThread( _Out_      PHANDLE ThreadHandle, _In_       ULONG DesiredAccess, _In_opt_   POBJECT_ATTR

cocos2dx2.0 与cocos2dx3.1 创建线程不同方式总结

虽然内容是抄过来的,但是经过了我的验证,而且放在一起就清楚很多了,cocos2dx版本经常变化很大,总会导致这样那样的问题. cocos2dx2.0 中 1. 头文件 #include <pthread.h> ... pthread_t serial_thread_id; // 起这个名字本打算用在socket上的 int serialThreadStart(void);// 启动线程的方法 static void* serialReceiverFun(void *arg);// 被启动的线程