Java线程池

1.线程池是什么

线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,这避免了在处理短时间任务时创建与销毁线程的代价

2.使用Excutors创建线程池的方法

Java里面的线程池的顶级接口时是Executor,Executor并不是一个线程池,而是一个执行线程的工具,真正的线程池是ExecutorService
(1) Executors.newFixedThreadPool(100); 创建固定大小的线程池
(2)Executors.newSingleThreadExecutor(); 创建只有一个线程的线程池
(3) Executors.newCachedThreadPool(); 创建一个不限线程数上限的线程池,任何提交的任务都将立即执行
(4) 对于服务器端需要长期运行的程序,创建线程池应该使用ThreadPoolExecutor的构造方法

构造方法参数列表;

  • corePoolSize: 线程池核心线程数
  • maximumPoolSize:线程池最大数
  • keepAliveTime: 空闲线程存活时间
  • unit: 时间单位
  • workQueue: 线程池所使用的缓冲队列
  • threadFactory:线程池创建线程使用的工厂
  • handler: 线程池对拒绝任务的处理策略

3.线程池4大特性

  • 当池中正在运行的线程数(包括空闲线程)小于corePoolSize时,新建线程执行任务
  • 当池中正在运行的线程数大于等于corePoolSize时,新插入的任务进入workQueue排队,等待空闲线程来执行
  • 当队列里的任务数达到上限,并且池中正在运行的线程数小于maximunPoolSize,对于新加入的任务,新建线程
  • 当队列里的任务数达到上限,并且池中正在运行的线程数等于maximunPoolSize,对于新加入的任务,执行拒绝策略(线程池默认的拒绝策略时抛异常)

4.线程池的种类

(1)newCachedThreadPool:核心线程数为0,最大线程数为Integer.MAX_VALUE

  • 作用:创建按一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们,并在需要时使用提供的ThreadFactory创建新线程
  • 特征:线程池中数量没有固定,可达到最大值;空闲线程的存活时间是60,线程池中的线程可进行缓存重复利用和回收;当线程池中没有可用线程时,会重新创建一个线程;工作队列是SynchronousQueue
  • 创建方式:Exectors.newCachedThreadPool();

(2)newFixedThreadPool:核心线程数与最大线程数均为指定的n Threads;空闲线程的空闲时间是0;工作队列是无界队列

  • 作用:创建一个可重用固定线程数的线程数,以共享的无界队列方式来运行这些线程
  • 特征:线程池中的数量处于一定的量,可以很好的控制线程的并发量;线程可以重复被使用,在显示关闭之前,都将一直存在;超出一定量的线程被提交时需要在队列中等待
  • 创建方式:
    (a)Executors.newFixedThreadPool(int nThreads);//nThreads为线程的数量
    (b) Executors.newFixedThreadPool(int nThreads,ThreadFactory threadFactory);//nThreads为线程的数量,threadFactory创建线程的工厂方式

(3)newSingleThreadExecutor:核心线程数与最大线程数均为1;工作队列是无界队列

  • 作用:创建一个使用单个worker线程的Executor,以队列方式来运行该线程(若在关闭前的执行期间出现失败而终止了此单个线程,如需要,一个新线程将代替它执行后续的任务);可保证顺序的执行各个任务,并且在任意给定的时间不会有多个线程是活动的
  • 特征:线程池中最多执行1个线程,之后提交的线程活动将会排在队列中依次执行
  • 创建方式:
    (a)Executors.newSingleThreadExecutor() ;
    (b)Executors.newSingleThreadExecutor(ThreadFactory threadFactory);// threadFactory创建线程的工厂方式

(4)newScheduledThreadPool:指定核心线程数corePoolSize;最大线程数是Integer.MAX_VALUE;DelayedWorkQueue:任务队列会根据任务延时时间的优先级进行执行

  • 作用:创建一个线程池,可安排在给定延迟后运行命令或者定期的执行
  • 特征:线程池中具有指定数量的线程,即便是空线程也将保留;可定时或者延迟执行线程活动
  • 创建方式:
    (a)Executors.newScheduledThreadPool(int corePoolSize);// corePoolSize线程的个数
    (b)newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory);// corePoolSize线程的个数,threadFactory创建线程的工厂

(5)newSingleThreadScheduledExecutor

  • 作用:创建一个单线程执行程序,可以安排在给定延迟后运行命令或者定期的执行
  • 特征:线程池中最多执行1个线程,之后提交的线程活动将会排在队列中依次执行;可定时或者延迟执行线程活动
  • 创建方式:
    (a)Executors.newSingleThreadScheduledExecutor() ;
    (b)Executors.newSingleThreadScheduledExecutor(ThreadFactory threadFactory);//threadFactory创建线程的工厂

5.工作队列

(1)SynchronousQueue:直接提交
工作队列的默认选项,将任务直接提交给线程而不保持;如果不存在可用于立即运行任务的线程,则试图将任务加入队列将失败,会构造一个新线程

  • 特点:可以避免在处理可能具有内部依赖性的请求集时出现锁;直接提交通常要求无界maximumPoolSizes以避免拒绝新提交的任务;当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程池具有增长的可能性

(2)ArrayBlockingQueue:有界队列
当与有限的maximumPoolSizes一起使用时,有界队列有助于防止资源耗尽,但是调整和控制会更加困难

队列大小和最大池大小相互权衡:

  • 使用大队列和小池可以最大程度地减少CPU使用率,操作系统资源和上下文切换开销,但可能会降低吞吐量
  • 如果任务频繁阻塞,系统可能可以为非预定的更多线程安排时间
  • 使用小队列通常需要更大的池,会使CPU繁忙,遇到不可接受的调度开销,这也会降低吞吐量

(3)LinkedBlockingQueue:无界队列
在所有核心线程都忙时,新任务在队列中等待,因此创建corePoolSize线程即可;当每个任务完全独立于其他任务时,不会相互影响

  • 特点:在网页服务器中,对消除短暂的突发请求很有用;当命令请求到达速度比其处理速度更快时,工作队列无限制增长

6.拒绝策略

(1)AbortPolicy:处理程序遭到拒绝将抛出运行时异常:RejectedExecutionException
(2)DiscardPolicy:不能执行的任务将被删除
(3)DiscardOldestPolicy:如果执行程序没有关闭,则位于工作队列头部的任务将被删除,然后重新执行程序(若再次失败,重复此过程)
(4)CallerRunsPolicy:线程调用运行该任务的execute本身,提供简单的反馈控制机制,能够减缓新任务的提交速度

7.使用线程池的优点

  • 重用线程池的线程,避免因为线程的创建和销毁锁所带来的性能开销
  • 有效控制线程池的最大并发数,避免大量的线程之间因抢占系统资源而阻塞
  • 能够对线程进行简单的管理,并提供特定的操作:定时、定期、单线程、并发数控制等功能

参考链接:https://blog.csdn.net/JAck_chen0309/article/details/105250643

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值