Merge pull request #37 from HuaHero/HuaHero-patch-35

Update Java 并发.md
This commit is contained in:
HuaHero 2023-12-15 16:49:24 +08:00 committed by GitHub
commit 0cd6e109c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -229,16 +229,15 @@ JDK1.5新增了Lock接口及其实现类,提供了更为灵活的同步方式。
【线程池的意义】
线程池可以有效地管理线程:它可以**管理线程的数量**,可以避免无节制的创建线程,导致超出系统负荷直至崩溃。它还可以**让线程复用**,可以大大地减少创建和销毁线程所带来的开销。
【**线程池的核心参数**】
线程池需要依赖一些参数来控制任务的执行流程,其中最重要的参数有corePoolSize核心线程数、workQueue等待队列、maxinumPoolSize最大线程数、handler拒绝策略、keepAliveTime空闲线程存活时间
线程池需要依赖一些参数来控制任务的执行流程,其中最重要的参数有corePoolSize核心线程数、workQueue等待队列、maximunPoolSize最大线程数、handler拒绝策略、keepAliveTime空闲线程存活时间
【线程池的运作步骤】
当我们向线程池提交一个任务之后,线程池按照如下步骤处理这个任务:
1. 判断线程数是否达到corePoolSize,若没有则新建线程执行该任务,否则进入下一步。
2. 判断等待队列是否已满,若没有则将任务放入等待队列,否则进入下一步。
3. 判断线程数是否达到maxinumPoolSize,如果没有则新建线程执行任务,否则进入下一步。
3. 判断线程数是否达到maximunPoolSize,如果没有则新建线程执行任务,否则进入下一步。
4. 采用初始化线程池时指定的拒绝策略,拒绝执行该任务。
5. 新建的线程处理完当前任务后,不会立刻关闭,而是继续处理等待队列中的任务。如果线程的空闲时间达到了keepAliveTime,则线程池会销毁一部分线程,将线程数量收缩至corePoolSize。 第2步中的队列可以有界也可以无界。若指定了无界的队列,则线程池永远无法进入第3步,相当于废弃了maxinumPoolSize参数。这种用法是十分危险的,如果任务在队列中产生大量的堆积,就很容易造成内存溢出。
6.
5. 新建的线程处理完当前任务后,不会立刻关闭,而是继续处理等待队列中的任务。如果线程的空闲时间达到了keepAliveTime,则线程池会销毁一部分线程,将线程数量收缩至corePoolSize。 第2步中的队列可以有界也可以无界。若指定了无界的队列,则线程池永远无法进入第3步,相当于废弃了maximunPoolSize参数。这种用法是十分危险的,如果任务在队列中产生大量的堆积,就很容易造成内存溢出。
【线程池池创建工具--建议用**ThreadPoolExecutor**】
JDK为我们提供了一个名为Executors的线程池的创建工具,该工具创建出来的就是带有无界队列的线程池,所以一般在工作中我们是不建议使用这个类来创建线程池的。 第4步中的拒绝策略主要有4个让调用者自己执行任务、直接抛出异常、丢弃任务不做任何处理、删除队列中最老的任务并把当前任务加入队列。这4个拒绝策略分别对应着RejectedExecutionHandler接口的4个实现类,我们也可以基于这个接口实现自己的拒绝策略。 在Java中,线程池的实际类型为ThreadPoolExecutor,它提供了线程池的常规用法。该类还有一个子类,名为ScheduledThreadPoolExecutor,它对定时任务提供了支持。在子类中,我们可以周期性地重复执行某个任务,也可以延迟若干时间再执行某个任务。