池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。
四个环节,七个参数(自查)
- 四个环节
任务队列: 存储待执行的任务。线程池从中获取任务进行执行。常见的队列类型有
LinkedBlockingQueue
和ArrayBlockingQueue
。线程池管理: 负责管理线程的生命周期,包括线程的创建、销毁等。管理策略可以通过配置来控制线程池的行为。
线程工厂: 创建新线程的工厂类。通常用于自定义线程的创建方式和线程属性。
拒绝策略: 当任务队列已满且线程池也无法处理更多任务时,线程池的拒绝策略决定如何处理新提交的任务。常见的拒绝策略包括
AbortPolicy
和CallerRunsPolicy
。
- ThreadPoolExecutor 七大参数
rejectedExecutionHandler:拒绝执行异常
总结:
- scheduleThreadPoolExecutor
ScheduledExecutorService继承ExecutorService接口
- Executor
Executor
框架不仅包括了线程池的管理,还提供了线程工厂、队列以及拒绝策略等, Executor
框架让并发编程变得更加简单。
`Executor` 是 Java 中 `java.util.concurrent` 包的一部分,它是一个用于处理异步任务的接口。`Executor` 提供了一种将任务提交给线程池或其他执行机制的方式,而无需直接处理线程创建和管理。`Executor` 接口
`Executor` 接口定义了一个简单的方法:
```java
void execute(Runnable command);
```这个方法用于提交一个 `Runnable` 任务,线程池会在适当的时候执行它。`Executor` 不提供任务调度或管理的能力,仅负责执行提交的任务。
### 常用实现
1. **`ThreadPoolExecutor`**:
- 这是 `Executor` 的一个强大实现,提供了一个线程池来管理线程和任务的调度。它允许配置线程池的大小、任务队列、线程工厂等。2. **`ScheduledThreadPoolExecutor`**:
- 继承自 `ThreadPoolExecutor`,实现了 `ScheduledExecutorService` 接口,支持任务的延迟执行和周期性执行。3. **`Executors` 工具类**:
- `Executors` 类提供了一些静态工厂方法,用于创建
ThreadPoolExecutor
3 个最重要的参数:
corePoolSize
: 任务队列未达到队列容量时,最大可以同时运行的线程数量。
maximumPoolSize
: 任务队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
workQueue
: 新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
ThreadPoolExecutor
其他常见参数 :
keepAliveTime
:线程池中的线程数量大于corePoolSize
的时候,如果这时没有新的任务提交,核心线程外的线程不会立即销毁,而是会等待,直到等待的时间超过了keepAliveTime
才会被回收销毁。
unit
:keepAliveTime
参数的时间单位。
threadFactory
:executor 创建新线程的时候会用到。
handler
:拒绝策略。
- 线程池常见的四个拒绝策略
AbortPolicy:直接抛出 RejectedExecutionException 异常,表示任务被拒绝。
CallerRunsPolicy:由提交任务的线程直接执行任务。这样可以减轻线程池的负担。
DiscardPolicy:默默丢弃被拒绝的任务,不抛出异常也不进行任何处理。
DiscardOldestPolicy:丢弃线程池中最旧的任务,然后尝试提交新的任务。
-
ThreadLocal和线程池
ThreadLocal
: 这是一个用于保存每个线程私有变量的类。每个线程都能拥有一个独立的变量副本,这样可以避免线程间的共享数据问题,保证线程安全。线程池: 用于管理和复用线程,以便高效执行并发任务。线程池维护了一组线程,这些线程可以被多个任务复用,减少了线程创建和销毁的开销。
关系
线程隔离: 在线程池中,
ThreadLocal
可以确保每个线程处理的任务能够访问到线程私有的数据,而不会受到其他线程的干扰。这对于需要线程隔离的数据,如数据库连接或用户会话信息,特别有用。资源共享: 在线程池中,多个线程会共享相同的
ThreadLocal
实例,但每个线程的ThreadLocal
变量是独立的。这意味着你可以在不同的线程中存储不同的数据,而无需担心线程安全问题。性能优化: 使用线程池结合
ThreadLocal
可以提升性能,因为线程池减少了线程创建的开销,而ThreadLocal
提供了线程隔离的数据存储方式,避免了不必要的同步操作。在实际应用中,
ThreadLocal
结合线程池使用时,需要注意线程的生命周期和ThreadLocal
变量的清理,确保在任务执行完毕后能够正确地释放ThreadLocal
变量,避免内存泄漏。
-
ThreadLocal
ThreadLocal
对象可以提供线程局部变量,每个线程Thread
拥有一份自己的副本变量,多个线程互不干扰。
Thread
类有一个类型为ThreadLocal.ThreadLocalMap
的实例变量threadLocals
,也就是说每个线程有一个自己的ThreadLocalMap
。
ThreadLocalMap
有自己的独立实现,可以简单地将它的key
视作ThreadLocal
,value
为代码中放入的值(实际上key
并不是ThreadLocal
本身,而是它的一个弱引用)。每个线程在往
ThreadLocal
里放值的时候,都会往自己的ThreadLocalMap
里存,读也是以ThreadLocal
作为引用,在自己的map
里找对应的key
,从而实现了线程隔离。
ThreadLocalMap
有点类似HashMap
的结构,只是HashMap
是由数组+链表实现的,而ThreadLocalMap
中并没有链表结构。我们还要注意
Entry
, 它的key
是ThreadLocal<?> k
,继承自WeakReference
, 也就是我们常说的弱引用类型。
ThreadLocal =new 单例模式