java基础学习——多线程之线程池

lycx      2022-04-20     477

关键词:

1.线程池介绍

    线程池是一种线程使用模式。线程由于具有空闲(eg:等待返回值)和繁忙这种不同状态,当数量过多时其创建、销毁、调度等都会带来开销。线程池维护了多个线程,当分配可并发执行的任务时,它负责调度线程执行工作,执行完毕后线程不关闭而是返回线程池,可以执行后续其他任务。举例来说,外卖餐厅对每个订单分配一个临时工,完成订单立刻辞退,成本和管理开销巨大,而且如果取餐点的空间有限,大量的人挤满在那反而会影响工作效率,因此选择签下固定数量的外卖小哥让他们不断往返于目的地和店家之间配送。

    通俗来讲,线程池就是为了减少开销而复用线程,实现了任务内容和线程分离的一种机制。如果机器有100核而且其他资源充足,直接启动100个无冲突的并发线程应该是比使用线程池要快,但是受限于目前的硬件能力,线程池就很有必要了。Java的Executor框架用于执行异步任务,方法 executor(Runnable runnable) 可以接收Runnable对象。Executor有一个子类接口ExecutorService,提供了生命周期管理的方法,以及可跟踪一个或多个异步任务执行状况返回Future的方法。

2.工厂模式创建线程池

     Excutors运用工厂模式提供线程池实现方式,返回ExecutorService

  1. newSingleThreadExecutor,单线程的线程池,实际上是串行执行任务,如果该线程出现异常则会有新线程替代它工作,其优势是任务会按照提交顺序执行。

  2. newFixedThreadPool,固定大小线程池,每次新提交任务时如果线程数没达到最大就创建新线程执行任务,否则任务进入等待状态。

  3. newCachedThreadPool,可缓存的线程池,大小依赖于操作系统(JVM)最大值。线程池大于任务数时回收部分空闲(60s)线程,任务数增加时添加新线程。

    问题在于,前两者请求处理队列的堆积会消耗内存,第三个创建过多线程也会这样。同时,拒绝策略在Executors中无效。

3.自定义创建

    ThreadPoolExecutor是线程池的实现方法签名:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) //后两个参数为可选参数

 

  1. corePoolSize,核心线程数,同时处于执行状态的线程最大值(或者说,接单配送中的小哥人数上限)。当线程数少于该值时,新的任务会创建新的线程执行。allowCoreThreadTimeOut属性不设置为true(默认false)时,闲置的核心线程也不会销毁。
  2. maximumPoolSize,线程总数,等于核心线程+非核心线程数,不小于核心线程数。
  3. keepAliveTime,线程进入不活跃状态后到销毁前的时间,通过Unit参数设置单位。通常只适用于非核心线程,allowCoreThreadTimeOut为true时核心线程也适用。
  4. workQueue,任务队列,当核心线程满时新任务进入该队列等待,当队列满时创建非核心线程执行任务。
    • SynchronousQueue:等于没有队列,任何任务都直接给线程处理,为防止线程数量达到最大值,通常设置maximumPoolSize为Integer.MAX_VALUE
    • LinkedBlockingQueue:无限长阻塞队列,总线程数永远等于核心线程数,未执行的任务都在队列里排队
    • ArrayBlockingQueue:定长队列,队列满时新建非核心线程,达到maximumPoolSize后出错
    • DelayQueue,当任务实现Delayed接口时,任务入队等待到指定延时后开始执行
  5. threadFactory,线程工厂
  6. handler,任务被拒绝时的策略
    • AbortPolicy,默认策略,将抛出RejectExecutorException
    • CallerRunsPolicy,线程池未关闭时调用线程(任务提交者)直接执行该任务
    • DiscardPolicy,直接丢弃不抛出异常
    • DiscardOldestPolicy,丢弃队列最前的任务后重试当前任务

4.生命周期

    ExecutorService的生命周期包括了运行、关闭和终止三种状态,在初始化创建时处于运行状态。使用submit方法执行Runnable或者Callable对象。shutdown方法等待提交的任务执行完成并不再接受新任务,在完成全部提交的任务后关闭;shutdownNow方法将强制终止所有运行中的任务并不再允许提交新任务。

 

java基础之多线程总结三(aqsthreadlocal和线程池)(代码片段)

AQS多线程里很多新型锁实现的关键是AQS,AQS指的是AbstractQueuedSynchronizer这个类,整个锁实现过程的关键是CAS操作加volatile。拿ReentrantLock非公平锁的lock和unlock举例,首先lock的源码中调用过程如下:ReentrantLock.lock()--&g... 查看详情

高并发多线程基础之线程池(代码片段)

高并发多线程之线程基础中生命周期、线程封闭、cpu缓存前言本篇文章描述我们jdk给我们提供的线程池;了解为什么使用线程池,有哪些优点,以及几种Executors中提供给我们的工厂创建方法等线程池的原理为什么要使... 查看详情

java基础学习——多线程之创建任务

  这次来盘点一下Java中用线程执行任务的写法。1.扩展Thread  最基本的实现方法是在创建一个继承Thread的新类,在其中覆盖run()方法执行任务。1publicclassMyThreadextendsThread{2//变量3privateStringname="";4//构造函数5publicMyThrea... 查看详情

c#多线程之线程池篇2

  在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度、实现取消选项的相关知识。三、线程池和并行度  在这一小节中,我... 查看详情

java多线程之线程池

1、什么是线程池?线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。2、线程池的优点使用线程池可以有效控制系统中并发线程的数量,当系统包含... 查看详情

c#多线程之线程池篇3

  在上一篇C#多线程之线程池篇2中,我们主要学习了线程池和并行度以及如何实现取消选项的相关知识。在这一篇中,我们主要学习如何使用等待句柄和超时、使用计时器和使用BackgroundWorker组件的相关知识。五、使用等待句... 查看详情

java多线程系列--“juc线程池”02之线程池原理

...tps://www.cnblogs.com/skywang12345/p/3509941.html概要在上一章"Java多线程系列--“JUC线程池”01之线程池架构"中,我们了解了线程池的架构。线程池的实现类是ThreadPoolExecutor类。本章,我们通过分析ThreadPoolExecutor类,来了解线程池的原理。... 查看详情

java多线程系列--“juc线程池”03之线程池原理

...://www.cnblogs.com/skywang12345/p/3509954.html概要在前面一章"Java多线程系列--“JUC线程池”02之线程池原理(一)"中介绍了线程池的数据结构,本章会通过分析线程池的源码,对线程池进行说明。内容包括:线程池示例参考代码(基于JDK1.7.0_4... 查看详情

java多线程系列--“juc线程池”03之线程池原理

线程池示例在分析线程池之前,先看一个简单的线程池示例。importjava.util.concurrent.Executors;importjava.util.concurrent.ExecutorService;publicclassThreadPoolDemo1{publicstaticvoidmain(String[]args){//创建一个可重用固定线程数的线程池ExecutorServi 查看详情

java基础(26):thread线程创建线程池

1.多线程1.1多线程介绍学习多线程之前,我们先要了解几个关于多线程有关的概念。进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功... 查看详情

java多线程学习线程池与executor框架

...优质文章推荐:Java并发编程指南专栏分布式系统的经典基础理论可能是最漂亮的Spring事务管理详解面试中关于Java虚拟机(jvm)的问题看这篇就够了目录:[TOC]本节思维导图:思维导图源文件+思维导图软件关注微信公众号:“ 查看详情

java多线程系列--“juc线程池”04之线程池原理

本章介绍线程池的生命周期。线程有5种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态。线程池也有5种状态;然而,线程池不同于线程,线程池的5种状态是:Running, SHUTDOWN, STOP, TIDYING, TERMINATED。线... 查看详情

java多线程系列--“juc线程池”02之线程池原理

ThreadPoolExecutor简介ThreadPoolExecutor是线程池类。对于线程池,可以通俗的将它理解为"存放一定数量线程的一个线程集合。线程池允许同时运行的线程数量就是线程池的容量;当添加到线程池中的线程超过它的容量时,会有一部分... 查看详情

java多线程系列--“juc线程池”05之线程池原理

拒绝策略介绍线程池的拒绝策略,是指当任务添加到线程池中被拒绝,而采取的处理措施。当任务添加到线程池中之所以被拒绝,可能是由于:第一,线程池异常关闭。第二,任务数量超过线程池的最大限制。线程池共包括4种... 查看详情

多线程之死锁就是这么简单(代码片段)

...dLocal就是这么简单多线程三分钟就可以入个门了!多线程基础必要知识点!看了学习多线程事半功倍Java锁机制了解一下AQS简简单单过一遍Lock锁子类了解一下线程池你真不来了解一下吗?本篇主要是讲解死锁,这是我在多线程的... 查看详情

java多线程之基本概念

01. Java多线程系列--“基础篇”01之基本概念Java多线程学习(吐血超详细总结) 查看详情

java线程和多线程——线程池基础

Java线程池管理多个工作线程,其中包含了一个队列,包含着所有等待被执行的任务。开发者可以通过使用ThreadPoolExecutor来在Java中创建线程池。线程池是Java中多线程的一个重要概念,因为通过Thread模型来控制多线程是... 查看详情

java基础之多线程知识懂多少

线程基本创建和启动方式不考虑线程池的情况下,创建和启动线程的基本方式有如下几种1.直接newThread类或者子类,2.实现runnable接口然后传递给Thread,这种方式更加灵活3.使用lambda表达式,实际上是实现runnable另一种写... 查看详情