多线程——java线程池简介(代码片段)

小兀哥 小兀哥     2022-12-01     152

关键词:

      上次我们回忆了多线程的基础概念,今天,我们来看看Java中对线程池的使用。

一、线程池

1、为什么需要

      在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些”池化资源”技术产生的原因。

2、是什么

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。

3、有什么好处

      第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
      第二:提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
      第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。但是要做到合理的利用线程池,必须对其原理了如指掌。

二、Executors提供

1、newCachedThreadPool

      创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

2、newFixedThreadPool

      创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

3、newScheduledThreadPool

      创建一个定长线程池,支持定时及周期性任务执行。

4、newSingleThreadExecutor

       创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

三、ThreadPoolExecutor提供

1、四个构造方法

public class ThreadPoolExecutor extends AbstractExecutorService 
    .....
    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
            BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler);

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,
        BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
    ...

2、参数解释

corePoolSize:

      核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

maximumPoolSize:

      线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;

keepAliveTime:

      表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

unit:

      参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒

workQueue:

      一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。

threadFactory:

线程工厂,主要用来创建线程;

handler:

表示当拒绝处理任务时的策略,有以下四种取值:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。 
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务 

总结:

      今天我们简单了解了一下为什么要用线程池,以及线程池的一些类型和使用,下次我们将继续深入学习线程池的原理。

java基础--28.线程池简介以及实际应用(代码片段)

线程池简介  程序启动一个新线程的成本是比较高的,因为它涉及到要与操作系统进行交互。  而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。  ... 查看详情

java多线程-12(线程管理中的线程池)(代码片段)

                              线程池                                               个人博客:www.xiaobeigua.icu1.2 线程池        线程池就是有效使用线程的一种常用方式。线程池内... 查看详情

java多线程进阶线程池(代码片段)

目录1、线程存在的问题 2、池化技术3、线程池4、Java中的线程池5、线程池的原理5.1、七大核心参数5.2、初始化核心线程5.3、addWorker:添加工作线程5.4、worker:工作线程5.5、runWorker:运行工作线程5.6、getTask:获取... 查看详情

java多线程进阶线程池(代码片段)

目录1、线程存在的问题 2、池化技术3、线程池4、Java中的线程池5、线程池的原理5.1、七大核心参数5.2、初始化核心线程5.3、addWorker:添加工作线程5.4、worker:工作线程5.5、runWorker:运行工作线程5.6、getTask:获取... 查看详情

java多线程:线程池详解(代码片段)

文章目录线程池注意点:线程池都有哪些状态?谈谈线程池的拒绝策略?线程池的队列大小通常怎么设置?1.CPU密集型任务2.IO密集型任务3.混合型任务线程池有哪些参数,各个参数的作用是什么?线程池注意点:... 查看详情

java多线程简介和简单使用(代码片段)

Java多线程简介1.线程简介1.1.线程概念1.2.进程概念1.3.线程作用1.4.进程和线程的联系2.线程执行2.1.示例2.2.解释2.3.线程在内存中的分配2.4.创建线程2.4.1.继承Thread类2.4.2.实现Runnable接口2.4.3.对比3.前台线程和后台线程1.线程简介1.1.线... 查看详情

java多线程:线程池详解(代码片段)

目录1.什么是线程池2.为什么要使用线程池3.线程池创建3.1 固定数量的线程池(Executors.newFixedThreadPool) 3.1.1创建固定数量的线程池3.1.2 线程池返回结果3.1.3submit()VSexecut()3.2.4线程工厂3.2 带缓存的线程池(Executors.newCac... 查看详情

多线程(线程池原理)(代码片段)

背景阿里电面-线程池是如何实现的?这个问题的侧重点是什么?普通的数据库连接池的概念一般是这样的,多个被静态代理或者动态代理生成的数据库连接,直接放到一个池子里,比方说一个队列,这个数据库连接池提供了如... 查看详情

java线程池spring线程池多线程知识总结(代码片段)

jdk线程池线程池的几个重要参数线程池有有界/无界队列、拒绝策略、核心线程数、最大线程数、空闲时间这几个重要参数,线程池的执行流程是,来了一个任务,如果核心线程数未满,则创建线程执行;如果... 查看详情

多线程--executor线程池框架(代码片段)

...在Java5之后,并发编程引入了一堆新的启动、调度和管理线程的API。其内部使用了线程池机制,它在java.util.cocurrent包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java5之后,通过Executor来... 查看详情

多线程使用线程池实现一个简单线程池(代码片段)

@TOC为什么要引入线程池我们知道我们每次创建启动销毁一个线程的消耗是较大的所以引入线程池的最大的好处就是减少每次启动销毁线程的损耗那么他是如何实现减少的?简单举个例子:为什么线程池子比系统申请释放快?为了... 查看详情

java多线程线程池的生命周期及运行状态(代码片段)

(目录)一、说明线程池的生命周期线程池的状态runState和工作线程数量workerCount共同保存在AtomicInteger类型的控制变量ctl中ctl高三位保存运行状态(2^3^=8>5),低29位保存工作线程的数量(2^29^-1) //初始运行状态为RUNNING,线程数为0privat... 查看详情

java多线程案例之线程池(代码片段)

文章目录一.线程池概述1.什么是线程池2.Java标准库提供的线程池二.线程池的简单实现一.线程池概述1.什么是线程池线程池和和字符串常量池,数据库连接池一样,都是为了提高程序的运行效率,减少开销;随着并发程度的提高,当我们... 查看详情

线程池(代码片段)

一、简介什么是线程池线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。为什么要用线程池如果并发请求数量很多,但每个线程执行的时间很短,就会出现频繁的创建和销毁线... 查看详情

java多线程(工具篇)(代码片段)

线程池原理线程池的七大参数详解:intcorePoolSize:该线程池中核心线程数最大值。核心线程:线程池中有两类线程,核心线程和非核心线程。核心线程默认情况下会一直存在于线程池中,即使这个核心线程什... 查看详情

java线程池(代码片段)

前言:线程池技术是通过对线程资源的统一管理来达到对线程资源的重复利用,降低线程频繁创建和销毁的开销。javajdk在java.util.concurrent并发包中有一套现成的对线程池的实现方案,我们可以直接拿来使用,快速实现多线程并发... 查看详情

java线程和线程池(代码片段)

标题线程为什么我们需要多线程呢?线程的生命周期/状态开启一个新线程守护线程取得线程的返回值FutureTask缺点线程池为什么我们需要线程池呢?线程池的生命周期/状态创建一个线程池自定义newCachedThreadPoolnewSingleThreadP... 查看详情

多线程三(线程组和线程池)(代码片段)

线程组和线程池一.线程组1.线程组介绍及使用Java使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许直接对线程组进行控制。对线程组的控制相当于控制这批线程。在默认情况下,子线程和创建它的父线程同... 查看详情