龙空技术网

Java线程池原理全面详解(图文版)

mikechen的互联网架构 638

前言:

眼前我们对“java线程详解”大致比较讲究,看官们都想要分析一些“java线程详解”的相关知识。那么小编同时在网络上网罗了一些对于“java线程详解””的相关资讯,希望大家能喜欢,各位老铁们快快来了解一下吧!

线程池作为一种池化技术,不仅在并发编程里占据了非常重要的位置,也是大厂常问的内容了,为什么需要线程池?线程池的流程原理?线程池有什么风险?等等,本篇就来谈谈这些线程池的关键点@mikechen

为什么需要线程池

在Java应用程序中,线程池是一种常见的技术,它提供了一种管理和复用线程的方式,可以显著提高应用程序的性能和可伸缩性。

如果线程数量多的话,频繁的创建和销毁线程会大大浪费时间和效率,更重要的是浪费内存。

那么有没有一种方法能让线程运行完后不立即销毁,而是让线程重复使用,继续执行其他的任务哪?

有,这种方式就是线程池,线程池中的线程可以重复使用,而不是在每次需要执行任务时创建新的线程,这样可以减少线程创建和销毁的开销,提高应用程序的性能。

线程池的使用风险

并不是说用了线程池就万事大吉,其实使用线程池也是有很多风险的。

比如:同步错误和死锁,还有诸如与池有关的死锁、资源不足和线程泄漏等问题。

1.死锁

死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种互相等待的现象,导致它们都被永久阻塞,无法继续执行下去。

死锁的原因是资源的竞争和互相等待,它通常发生在多线程并发执行的情况下,尤其是当线程需要获取多个锁时,如果线程之间相互等待对方释放锁,就会导致死锁的发生。

例如,线程A和线程B分别持有锁1和锁2,它们同时需要获取对方持有的锁,但是对方不释放锁,这时就会导致死锁的发生。

如下图所示:

其实:任何多线程应用程序都有死锁风险。

2.资源不足

线程消耗包:括内存和其它系统资源在内的大量资源。

比如: 线程创建对象都需要内存空间。

除此以外,JVM 可能会为每个 Java 线程创建一个本机线程,这些本机线程将消耗额外的系统资源。

虽然线程之间切换的调度开销很小,但如果有很多线程,环境切换也可能严重地影响程序的性能。

如果线程池太大,那么被那些线程消耗的资源可能严重地影响系统性能。

3.线程泄漏

各种类型的线程池中一个严重的风险是线程泄漏,当从线程池中除去一个线程以执行一项任务,而在任务完成后该线程却没有返回池时,会发生这种情况。

发生线程泄漏的一种情形出现在任务抛出一个 RuntimeException 或一个 Error 时。

如果没有捕捉到它们,那么线程只会退出而线程池的大小将会永久减少一个,当这种情况发生的次数足够多时,线程池最终就为空,而且系统将停止。

因为没有可用的线程来处理任务。

线程池的实现原理

1.线程池组成

Java线程池主要由以下几个部分组成:

线程池管理器:负责创建和管理线程池。工作线程:线程池中实际执行任务的线程。任务队列:用于存储等待执行的任务。任务接口:定义任务的执行方法。

2.线程池的工作原理

线程池的工作原理,如下图所示:

主要分为如下流程:

1.检查线程池是否已满

当一个任务需要执行时,线程池会检查线程池中是否有空闲的线程可用,如果有,那么一个空闲的线程会被分配给该任务执行。

2.将任务放入队列

如果线程池中没有空闲的线程可用,那么任务会被放到任务队列中等待执行,直到有空闲的线程可用。

3.准备开始处理任务

当一个线程完成了任务的执行后,它会返回线程池,并且准备处理下一个任务。

4.如果已满执行拒绝策略

如果线程池中的线程数量已经达到了限制,而且任务队列已经满了,那么线程池会拒绝该任务并执行拒绝策略。

以上

更多分布式架构系列、阿里架构师进阶系列,请查看以下文章:

阿里架构师进阶从0到1全部合集(建议收藏)

标签: #java线程详解