目录
1.什么是线程池
2.标准库中的线程池
2.1各个参数什么意思
int corePoolSize:
int maximumPoolSize:
keepAliveTime:
BlockingQueue workQueue:
ThradFactory threadFactory :线程工厂
RejectedExecutionHandler handler:(面试可能会问)
3.实现一个线程池
1.什么是线程池
线程池是一种管理和复用线程的机制。它通过预先创建一组线程并维护它们的生命周期,以便在需要时重复使用这些线程,可以减少线程创建和销毁的开销。
为什么要用线程池呢
在我们使用多线程进行开发编程的时候,使用多线程确实可以进行并发编程,但是频繁的创建和销毁线程会消耗很多的资源,开销较大。所以我们引入线程池,将需要用的线程,在线程池中准备好,用的时候从线程池中拿,用完又放回到线程池中。这样就可以减小开销。
2.标准库中的线程池
在标准库中我们用ThreadPoolExecutor类来表示线程池。ThreadPoolExecutor 提供了更多的可选参数, 可以进⼀步细化线程池⾏为的设定.
2.1各个参数什么意思
int corePoolSize:
核心线程数。就像在一家公司里的正式员工,。当你被录用了后,就不会被辞退。对公司来说很重要。核心线程数也是一样,在一个进程里是非常重要的。
int maximumPoolSize:
最大线程数。就像是一家公司里的正式员工+实习生。实习生⼀段时间不⼲活, 就被辞退。
keepAliveTime:
保持存活时间。就像实习生允许的空闲时间.如果实习生空闲时间超过这个时间就会被辞退。在线程里就表示线程空闲的时间。超过这个时间就会被销毁。
BlockingQueue<Runnable> workQueue:
和定时器类似,线程池中可以持有很多任务。以Runnable为对象。
ThradFactory threadFactory :线程工厂
线程工厂 通过这个工厂类来创建线程对象。线程工厂(Thread Factory)是用于创建线程的对象或方法。它提供了一种统一的方式来创建线程,并可以对线程进行自定义配置和初始化。线程工厂通常包含以下主要功能:
创建线程:线程工厂负责创建新的线程对象。通过线程工厂,可以使用特定的方式创建线程,例如设置线程的名称、优先级、线程组等属性。
配置线程:线程工厂允许对线程进行自定义配置和初始化。可以在创建线程时指定线程的运行环境、上下文、异常处理器等。
线程命名:线程工厂可以为创建的线程设置一个有意义的名称,以便在日志和调试中更好地追踪和识别线程。
线程工厂的作用是封装线程的创建过程,提供了一种可扩展和可定制的方式来创建线程。通过使用线程工厂,可以对线程进行统一管理和配置,使得线程的创建和使用更加灵活和可控。
RejectedExecutionHandler handler:(面试可能会问)
拒绝策略 在一个线程池中,有一个阻塞队列。能够容纳的元素有上限的,当任务队列满了,如果再往里加任务时,就会用到拒绝策略。
第一个策略: 继续添加任务时,会抛异常。新任务和旧任务都不运行了。
第二个策略:继续添加任务时,会抛异常。新的任务,由添加新任务的线程来执行。谁添加谁来执行。
第三个策略:继续添加任务时,会抛异常。旧的任务不执行了。执行新的任务。
第四个策略:继续添加任务时,会抛异常。丢弃最新的任务,新任务不会执行。
用标准库:
ExecutorService pool = Executors.newFixedThreadPool(10);
pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}
});
3.实现一个线程池
代码:
package 多线程;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;class MyThreadPoolExecutor{private List<Thread> threadList = new ArrayList<>();//就是一个用来保存任务的队列。private BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>(1000);//通过 n 指定创建多少个线程public MyThreadPoolExecutor(int n){for (int i = 0; i < n; i++) {Thread t = new Thread(()->{//线程要做的事情就是吧任务队列中的任务不停的取出来,并且进行执行while (true){try {//此处的 take 带有阻塞功能的//如果队列为空,此处 的 take 就会阻塞Runnable runnable = queue.take();//取出一个任务就执行一个任务runnable.run();} catch (InterruptedException e) {e.printStackTrace();}}});t.start();threadList.add(t);}}public void submit(Runnable runnable) throws InterruptedException{queue.put(runnable);}}public class ThreadDemo26 {public static void main(String[] args) throws InterruptedException {MyThreadPoolExecutor executor = new MyThreadPoolExecutor(4);for (int i = 0; i < 1000; i++) {int n = i;executor.submit(new Runnable() {@Overridepublic void run() {System.out.println("执行任务" + n + "当前线程为:" + Thread.currentThread().getName());}});}}
}
运行结果:我们可以看到任务不是按顺序执行的,因为当线程接到任务时,并不是立刻执行。所以任务3排到任务17后面去了。
本期分享结束,希望大家多多支持!!!