-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
02792fe
commit 028bc97
Showing
24 changed files
with
348 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# 2024年05月12日 | ||
|
||
- Spring Bean 注册 | ||
|
||
- Spring 三级缓存 | ||
|
||
- 一级缓存这样存放成品 Bean,不能解决循环依赖的问题的。因为 A 的成品创建依赖于 B,B的成品创建又依赖于 A,当需要补全B的属性时 A 还是没有创建完,所以会出现死循环。 | ||
|
||
- 二级缓存用于存放半成品对象,继续创建,创建的半成品同样放到缓存中。 | ||
- 三级缓存主要是解决 Spring AOP 的特性。AOP 本身就是对方法的增强,是 `ObjectFactory<?>` 类型的 lambda 表达式,而 Spring 的原则又不希望将此类类型的 Bean 前置创建,所以要存放到三级缓存中处理。 | ||
|
||
- 聊一下 ThreadLocal | ||
|
||
- `ThreadLocal` 底层采用的是数组结构存储数据。 | ||
- `new ThreadLocal<>().remove();` 操作。避免弱引用发生GC后,导致内存泄漏的问题。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# 四种线程池 | ||
|
||
Executors 是创建线程池的工具类,比较典型常见的四种线程池包括:newFixedThreadPool 、 newSingleThreadExecutor 、 newCachedThreadPool 、newScheduledThreadPool。 | ||
|
||
## newFixedThreadPool | ||
|
||
- 固定大小可重复使用的线程池,corePoolSize = maximumPoolSize | ||
- 以 LinkedBlockingQueue 无界阻塞队列存放等待线程。 | ||
- 随着线程任务不能被执行的的无限堆积,可能会导致 OOM | ||
|
||
```java | ||
public static ExecutorService newFixedThreadPool(int nThreads, | ||
ThreadFactory threadFactory) { | ||
return new ThreadPoolExecutor(nThreads, nThreads, | ||
0L, TimeUnit.MILLISECONDS, | ||
new LinkedBlockingQueue<Runnable>(), | ||
threadFactory); | ||
} | ||
``` | ||
|
||
![image-20240512112625906](./image/image-20240512112625906.png) | ||
|
||
## newSingleThreadExecutor | ||
|
||
- 只创建一个执行线程任务的线程池 | ||
- 如果出现意外终止则再创建一个 | ||
- 个无界队列存放待执行线程,无限堆积下会出现 OOM | ||
|
||
```java | ||
public static ExecutorService newSingleThreadExecutor() { | ||
return new FinalizableDelegatedExecutorService | ||
(new ThreadPoolExecutor(1, 1, | ||
0L, TimeUnit.MILLISECONDS, | ||
new LinkedBlockingQueue<Runnable>())); | ||
} | ||
``` | ||
|
||
## newCachedThreadPool | ||
|
||
- SynchronousQueue 是一个生产消费模式的阻塞任务队列,只要有任务就需要有线程执行,线程池中的线程可以重复使用。 | ||
- 如果线程任务比较耗时,又大量创建,会导致 OOM。 | ||
|
||
```java | ||
public static ExecutorService newCachedThreadPool() { | ||
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, | ||
60L, TimeUnit.SECONDS, | ||
new SynchronousQueue<Runnable>()); | ||
} | ||
``` | ||
|
||
## newScheduledThreadPool | ||
|
||
- 延迟定时执行,有点像我们的定时任务 | ||
- 无限大小的线程池 Integer.MAX_VALUE | ||
- 无限容量的线程池,所以依旧有 OOM 风险 | ||
|
||
```java | ||
public ScheduledThreadPoolExecutor(int corePoolSize) { | ||
super(corePoolSize, Integer.MAX_VALUE, | ||
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, | ||
new DelayedWorkQueue()); | ||
} | ||
``` | ||
|
||
## 总结 | ||
|
||
![img](./image/gcn3uiw2wg-20240512113446077.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# 线程池 | ||
|
||
为什么使用线程池:线程池的核心目的就是资源的利用,避免重复创建线程带来的资源消耗。因此引入一个池化技术的思想,避免重复创建、销毁带来的性能开销。 | ||
|
||
- 当需要多线程并发执行任务时,只能不断的通过new Thread创建线程,每创建一个线程都需要在堆上分配内存空间,同时需要分配虚拟机栈、本地方法栈、程序计数器等线程私有的内存空间,当这个线程对象被可达性分析算法标记为不可用时被GC回收,这样频繁的创建和回收需要大量的额外开销。 | ||
- JVM的内存资源是有限的,如果系统中大量的创建线程对象,JVM很可能直接抛出OutOfMemoryError异常,还有大量的线程去竞争CPU会产生其他的性能开销,更多的线程反而会降低性能,所以必须要限制线程数。 | ||
|
||
线程池好处: | ||
|
||
- 线程池可以复用池中的线程,不需要每次都创建新线程,减少创建和销毁线程的开销; | ||
- 线程池具有队列缓冲策略、拒绝机制和动态管理线程个数,特定的线程池还具有定时执行、周期执行功能 | ||
- 线程池可实现线程环境的隔离 | ||
|
||
## 执行流程 | ||
|
||
|
||
|
||
## 构造方法 | ||
|
||
![img](./image/mn820rtb6b.png) | ||
|
||
![img](./image/gcn3uiw2wg.png) | ||
|
||
## 核心参数 | ||
|
||
![img](./image/iq2cn7c9eu.png) | ||
|
||
- corePoolSize(int):核心线程数量。 | ||
- 默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到任务队列当中。线程池将长期保证这些线程处于存活状态,即使线程已经处于闲置状态。除非配置了allowCoreThreadTimeOut=true,核心线程数的线程也将不再保证长期存活于线程池内,在空闲时间超过keepAliveTime后被销毁。 | ||
- workQueue:阻塞队列,存放等待执行的任务,线程从workQueue中取任务,若无任务将阻塞等待。当线程池中线程数量达到corePoolSize后,就会把新任务放到该队列当中。JDK提供了四个可直接使用的队列实现,分别是:基于数组的有界队列ArrayBlockingQueue、基于链表的无界队列LinkedBlockingQueue、只有一个元素的同步队列SynchronousQueue、优先级队列PriorityBlockingQueue。在实际使用时一定要设置队列长度。 | ||
- maximumPoolSize(int):线程池内的最大线程数量,线程池内维护的线程不得超过该数量,大于核心线程数量小于最大线程数量的线程将在空闲时间超过keepAliveTime后被销毁。当阻塞队列存满后,将会创建新线程执行任务,线程的数量不会大于maximumPoolSize。 | ||
- keepAliveTime(long):线程存活时间,若线程数超过了corePoolSize,线程闲置时间超过了存活时间,该线程将被销毁。除非配置了allowCoreThreadTimeOut=true,核心线程数的线程也将不再保证长期存活于线程池内,在空闲时间超过keepAliveTime后被销毁。 | ||
- TimeUnit unit:线程存活时间的单位,例如TimeUnit.SECONDS表示秒。 | ||
- RejectedExecutionHandler:拒绝策略,当任务队列存满并且线程池个数达到maximunPoolSize后采取的策略。ThreadPoolExecutor中提供了四种拒绝策略,分别是:抛RejectedExecutionException异常的AbortPolicy(如果不指定的默认策略)、使用调用者所在线程来运行任务CallerRunsPolicy、丢弃一个等待执行的任务,然后尝试执行当前任务DiscardOldestPolicy、不动声色的丢弃并且不抛异常DiscardPolicy。项目中如果为了更多的用户体验,可以自定义拒绝策略。 | ||
- threadFactory:创建线程的工厂,虽说JDK提供了线程工厂的默认实现DefaultThreadFactory,但还是建议自定义实现最好,这样可以自定义线程创建的过程,例如线程分组、自定义线程名称等。 | ||
|
||
## 提交线程 execute | ||
|
||
通过execute方法提交任务时,当线程池中的线程数小于corePoolSize时,新提交的任务将通过创建一个新线程来执行,即使此时线程池中存在空闲线程。 | ||
|
||
![img](./image/u5x078fkiq.png) | ||
|
||
当线程池中线程数量达到corePoolSize时,新提交的任务将被放入workQueue中,等待线程池中线程调度执行。 | ||
|
||
![img](./image/ja4c974izo.png) | ||
|
||
当workQueue已存满,且maximumPoolSize大于corePoolSize时,新提交的任务将通过创建新线程执行。 | ||
|
||
![img](./image/30dkd7bmt0.png) | ||
|
||
当线程池中的线程执行完任务空闲时,会尝试从workQueue中取头结点任务执行。 | ||
|
||
![img](./image/8g7sroglys.png) | ||
|
||
|
||
|
||
当线程池中线程数达到maxmumPoolSize,并且workQueue也存满时,新提交的任务由RejectedExecutionHandler执行拒绝操作。 | ||
|
||
![img](./image/pihw1794iu.png) | ||
|
||
当线程池中线程数超过corePoolSize,并且未配置allowCoreThreadTimeOut=true,空闲时间超过keepAliveTime的线程会被销毁,保持线程池中线程数为corePoolSize。 | ||
|
||
![img](./image/0jgaovcjl8.png) | ||
|
||
当设置allowCoreThreadTimeOut=true时,任何空闲时间超过keepAliveTime的线程都会被销毁。 | ||
|
||
![img](./image/hppq1bllq4.png) | ||
|
||
## 线程池底层实现原理 | ||
|
||
![img](./image/zedywpyew6.png) | ||
|
||
线程池不同状态之间的转换时机及转换关系 | ||
|
||
![img](./image/ezyra2a98g.png) | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
> https://www.cnblogs.com/JavaYuYin/p/18012766 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.