java多线程:线程池和阻塞队列

一、线程池定义和使用

jdk 1.5 之后就引入了线程池。

1.1 定义

从上面的空间切换看得出来,线程是稀缺资源,它的创建与销毁是一个相对偏重且耗资源的操作,而Java线程依赖于内核线程,创建线程需要进行操作系统状态切换。为避免资源过度消耗需要设法重用线程执行多个任务。线程池就是一个线程缓存,负责对线程进行统一分配、调优与监控。(数据库连接池也是一样的道理)

什么时候使用线程池?

单个任务处理时间比较短;需要处理的任务数量很大。

线程池优势?

  • 重用存在的线程,减少线程创建、消亡的开销,提高性能、提高响应速度。
  • 当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 提高线程的可管理性,可统一分配,调优和监控。

1.2 线程池在 jdk 已有的实现

  • 在 juc 包下,有一个接口:Executor :
  • Executor 又有两个子接口:ExecutorService 和 ScheduledExecutorService,常用的接口是 ExecutorService。
  • 同时常用的线程池的工具类叫 Executors。

例如:

ExecutorService service = Executors.newCachedThreadPool();

Executor 框架虽然提供了如 newFixedThreadPool()、newSingleThreadExecutor()、newCachedThreadPool()、newScheduledThreadPool() 等创建线程池的方法,但都有其局限性,不够灵活。

上面的几种方式点进去会发现,都是用 ThreadPoolExecutor 进行创建的:

  1. newSingleThreadExecutor 字面意思简单线程执行器
    在这里插入图片描述
  2. newFixedThreadPool 字面意思固定的线程池,传参就是线程固定数目,适用于执行长期任务的场景。
    在这里插入图片描述
  3. newCachedThreadPool 字面意思缓存线程池,核心线程0,最大线程非常大,动态创建的特点。
    在这里插入图片描述
  4. newScheduledThreadPool 字面意思时间安排线程池,指定核心线程数。
    在这里插入图片描述
    在这里插入图片描述
  5. newSingleThreadScheduledExecutor 字面意思单线程安排执行器,也就是基于只有一个核心线程的执行器之外,又可以扩展。其中又用 DelegatedExecutorService 委托执行器服务进行了包装。
    在这里插入图片描述
    可以看到,上面直接用 Executors 工具类默认的一些实现 new 出来的线程池都是用的 ThreadPoolExecutor 线程执行器这个类进行构造的,不过参数不同,导致了效果的侧重点不同。

因此,自己创建线程池推荐的方法就是,直接使用 ThreadPoolExecutor 进行个性化的创建:

在这里插入图片描述
构造方法种的参数有 7 个:

  • corePoolSize:线程池维护线程的最少数量 (core : 核心
  • maximumPoolSize:线程池维护线程的最大数量,显然必须>=1
  • keepAliveTime:线程池维护的多余的线程所允许的空闲时间,最长可以空闲多久,时间到了,如果超过 corePoolSize 的线程一直空闲,他们就会被销毁。
  • unit:线程池维护线程所允许的空闲时间的单位
  • workQueue:线程池所使用的缓冲队列,已经提交但是没有执行的任务会放进这里
  • threadFactory:生成线程池种工作线程的线程工厂,一般使用默认
  • handler:线程池对拒绝任务的处理策略,当队列满且工作线程已经达到maximumPoolSize。

阿里的 java 开发手册,强制要求,通过 ThreadPoolExecutor 来自定义,不能使用内置的,避免资源耗尽。这个很好理解,1 的类型就只有一个核心线程和最大现场,2 没有扩展性,3、4、5的最大线程数太大,内存会爆炸。

1.3 线程池使用方法

这里我们用固定线程池来测试,传入核心线程数为 5,最大数量自然就也是 5,


                
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程中,线程池是一种重要的多线程管理机制。引用中的示例代码展示了如何使用线程池来执行任务。在示例中,通过创建一个线程池工厂,指定线程池的核心线程数、最大线程数、线程存活时间、任务队列等参数来创建线程池。然后循环提交任务给线程池,通过execute方法执行任务。每个任务会在一个空闲的线程中执行,实现了线程的复用和任务的异步执行。 另外,引用中的示例展示了如何使用定时任务的线程池。通过创建一个定时任务线程池,可以指定任务的延时时间、间隔时间和执行次数,从而实现定时执行任务的功能。 此外,引用提到了Java虚拟机使用的线程模型,即KLT内核级线程。KLT线程由系统内核管理,它保存线程的状态和上下文信息,并且线程阻塞不会引起进程阻塞。在多处理器系统上,多线程可以在多处理器上并行运行。KLT线程的创建、调度和管理由内核完成,相比于ULT用户级线程,KLT线程的效率较慢,但比进程操作快。 综上所述,Java多线程中的线程池是一种重要的多线程管理机制,可以实现线程的复用和任务的异步执行。同时,Java还支持定时任务的线程池和内核级线程模型。123 #### 引用[.reference_title] - *1* *2* *3* [java多线程线程池](https://blog.csdn.net/qq_29996285/article/details/118955325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值