ThreadPool线程池——线程复用——超级详细骗

本文详细介绍了Java线程池的工作原理、JDK的Executor框架支持,强调线程池在控制资源消耗、提高响应速度和管理线程方面的优势。讨论了线程池的核心实现ThreadPoolExecutor,包括核心线程数、最大线程数、存活时间等参数,以及不同类型的BlockingQueue对线程池行为的影响。此外,文章提到了线程池的拒绝策略和自定义线程创建,指出应避免使用Executors创建线程池,建议根据CPU密集型或IO密集型工作来合理配置maximumPoolSize。
摘要由CSDN通过智能技术生成

多线程的软件设计方法确实可以最大限度地发挥现代多核处理器的计算能力,提高生产系统的吞吐量和性能。但是,若不加控制和管理,随意使用线程,对系统的性能反而会产生不利的影响。

  Thread thread = new Thread(new CounterDemo());

在简单的应用系统中,这段代码并没有太多问题。但是在真实的生产环境中,系统由于真实环境的需要,可能会开启很多线程来支撑其应用。而当线程数量过大时,反而会耗尽CPU和内存资源。首先,虽然与进程相比,线程是一种轻量级的工具, 但其创建和关闭依然需要花费时间,如果为每一个小的任务都创建一一个线程,则很有可能出现创建和销毁线程所占用的时间大于该线程真实工作所消耗的时间的情况,反而会得不偿失。

其次,线程本身也是要占用内存空间的,大量的线程会抢占宝贵的内存资源,如果处理不当,可能会导致Out of Memory异常。即便没有,大量的线程回收也会给GC带来很大的压力,延长GC的停顿时间。

因此,对线程的使用必须掌握一个度, 在有限的范围内增加线程的数量可以明显提高系统的吞吐量,一旦超出了这个范围,大量的线程只会拖垮应用系统。因此,在生产环境中使用线程必须对其加以控制和管理。

1:线程池介绍

为了避免系统频繁地创建和销毁线程,我们可以让创建的线程复用。如果大家进行过数据库开发,那么对数据库连接池应该不会陌生。为了避免每次数据库查询都重新建立和销毁数据库连接,我我们可以使用数据库连接池维护一些些数据库连接,让它们长期保持在一个激活状态。当系统需要使用数数据库时,并不是创建一 个新的连接,而是从连接池中获得个可 用的连接即可。反之,当需要关闭连接时, 并不真的把连接关闭,而是将这个连接“还”给连接池即可。这种方式可以节约不少创建和销毁对象的时间。

线程池也是类似的概念。在线程池中,总有那么几个活跃线程。当你需要使用线程时,可以从池子中随便拿一个空闲线程, 当完成工作时,并不急着关闭线程,而是将这个线程退回到线程池中,方便其他人使用。

简而言之,在使用线程池后,创建线程变成了从线程池获得空闲线程,关闭线程变成了向线程池归还线程

线程池的优势:

线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。

它的主要特点为:线程复用;控制最大并发数;管理线程。

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的销耗。

第二:提高响应速度。当任务到达时,任务可以不需要等待线程创建就能立即执行。

第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

2:JDK对线程池的支持——Executor

为了可以更好的控制多线程,JDK提供了一套Executor框架,帮助我们有效地进行线程控制,其本质就是一个线程池,它的核心如下图
在这里插入图片描述
以上成员均在java.util.concurrent包中,是JDK并发包的核心类。其中,ThreadPoolExecutor表示一个线程池。Executors 类则扮演着线程池工厂的角色,通过Executors 可以取得一个拥有特定功能的线程池。从UML图中亦可知,ThreadPoolExecutor类实现了Executor接口,因此通过这个接口,任何Runable的对象都可以被ThreaPoolExecutor线程池调度。Executor框架提供了各种类型的线程池,主要有以下工厂方法

Executors
public static ExecutorService newFixedThreadPool (int nThreads)

public static ExecutorService newSingleThreadExecutor ()

public static ExecutorService newCachedThreadPool ()

public static ScheduledExecutorService newSingleThreadScheduledExecutor ()

public static ScheduledExecutorService newScheduledThreadPool (int corePoolSize)

以上工厂方法分别返回具有不同工作特性的线程池。这些线程池工厂方法的具体说明如下。
线程池——线程池创建的5种方法

3:核心线程池的内部实现——ThreadPoolExecutor

在这里插入图片描述

对于核心的几个线程池,无论是Executors中的newFixedThreadPool()方法、newSingleThreadExecutor()方法,还是newCachedThreadPool()方法,虽然看起来创建的线程有着完全的实现方式:但其内部实现均使用了ThreadPoolExecutor类。下面给出了这三个线程池的实现方式

    public static ExecutorService newFixedThreadPool(int nThreads) {
   
        return new ThreadPoolExecutor(nThreads
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值