泉州公司建设网站,dedecms怎么部署网站,建设网站的功能及目的是什么意思,wordpress 页脚目录
前言#xff1a;
线程池#xff1a;
线程池的工作流程#xff1a;
代码实现线程池#xff1a;
任务拒绝策略#xff1a;
线程池多大才算合适#xff1f;
总结#xff1a; 前言#xff1a; 在Java编程中#xff0c;线程池是一个强大的工具#xff0c;它能…目录
前言
线程池
线程池的工作流程
代码实现线程池
任务拒绝策略
线程池多大才算合适
总结 前言 在Java编程中线程池是一个强大的工具它能够管理和复用线程提供高效的并发处理能力。通过线程池我们可以有效地控制并发线程的数量并降低线程创建和销毁的开销。本文将引导你深入了解Java中的线程池探索其原理、用法和优势为你提供一个更高效的编程方式。 线程池的作用就是管理线程数量减少线程频繁的创建和销毁 线程池 线程池是一种用于管理和复用线程的技术它可以有效地处理并发任务并提高程序的性能和响应能力。线程池维护着一个线程队列其中包含了一定数量的线程。当有新的任务到达时线程池会从队列中选择一个空闲的线程来执行任务而不是为每个任务都创建新的线程。
线程池的工作流程 创建线程池包括初始化线程队列和创建指定数量的线程。 将任务提交给线程池。可以通过将任务对象提交给线程池的方式来添加新的任务。 线程池从任务队列中选择一个空闲的线程来执行任务。 执行任务。线程池中的线程会执行任务对象中定义的操作。 任务执行完成后线程返回线程池并等待下一个任务。 线程池继续从任务队列中选择新的任务并分配给空闲线程循环执行以上步骤。
代码实现线程池
1.创建线程池的工具类 ExecutorService
public static ExecutorService newCachedThreadPool() 创建一个没有上限的线程池public static ExecutorService newCachedThreadPool(int int nthread) 创建一个有上限的线程池 其实第一个创建线程池不是真正没有上限他的上限是int的最大范围只不过因为实在是太大了因此我们说没有上限。 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ThreadPoolExample {public static void main(String[] args) {// 创建一个固定大小为5的线程池ExecutorService threadPool Executors.newFixedThreadPool(5);// 提交任务给线程池for (int i 0; i 10; i) {final int taskId i;threadPool.execute(new Runnable() {public void run() {try {System.out.println(开始执行任务 taskId);Thread.sleep(2000); // 模拟任务执行时间System.out.println(任务执行完成 taskId);} catch (InterruptedException e) {e.printStackTrace();}}});}// 关闭线程池threadPool.shutdown();}
} 小技巧 通过打断点的方式我们可以实时看到当前线程池中的线程数量 2.自定义创建线程池对象 ThreadPoolExecutor
在Java中我们可以使用ThreadPoolExecutor来自定义创建线程池对象。ThreadPoolExecutor是ExecutorService接口的一个实现类它允许我们灵活地配置线程池的核心线程数、最大线程数、线程存活时间等参数。 首先我们需要导入java.util.concurrent包。然后可以通过以下代码创建一个自定义的线程池对象
public class test03 {public static void main(String[] args) {ThreadPoolExecutor pool new ThreadPoolExecutor(3,//核心线程数量6,//最大线程数60,//空闲线程最大存活时间TimeUnit.SECONDS,//时间单位new ArrayBlockingQueue(3),//指定任务队列最大长度Executors.defaultThreadFactory(),//创建线程工厂new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略);}
}在上述代码中我们传入了核心线程数、最大线程数、非核心线程空闲超时时间以及任务队列等参数来创建线程池对象。你还可以根据需要调整这些参数以满足你的实际需求。 核心线程数corePoolSize核心线程数是线程池中一直存活的线程数量。当提交一个任务时如果当前核心线程数还未达到设定的值线程池会创建新的核心线程来处理任务。即使核心线程处于空闲状态它们也不会被回收。 最大线程数maxPoolSize最大线程数是线程池中能容纳的最大线程数量。当提交的任务超过了核心线程数并且任务队列已满时线程池会创建新的线程来执行任务直到达到最大线程数。超过最大线程数的任务将会被拒绝执行。 非核心线程空闲超时时间keepAliveTime当线程池中的线程数量超过核心线程数并且这些线程处于空闲状态时非核心线程会被回收。空闲超时时间设定了非核心线程的最长存活时间超过这个时间空闲的非核心线程将被回收。 任务拒绝策略
在Java中任务拒绝策略用于处理线程池无法接受更多任务时的行为。当线程池已满并且工作队列已满或达到最大容量时新提交的任务可能会被拒绝执行。Java提供了四种默认的任务拒绝策略 AbortPolicy中止策略这是默认的任务拒绝策略。当线程池无法接受新任务时新提交的任务会立即抛出RejectedExecutionException异常。 CallerRunsPolicy调用者运行策略如果线程池无法接受新任务则由提交任务的线程来执行该任务。这意味着任务的执行将回退到调用线程中执行从而降低了整体的并发度。 DiscardPolicy丢弃策略当线程池无法接受新任务时新提交的任务将被静默丢弃不会抛出任何异常。这意味着被丢弃的任务将不会被执行。 DiscardOldestPolicy丢弃最旧策略当线程池无法接受新任务时线程池会丢弃工作队列中最旧的任务即最先提交的任务然后尝试再次提交新任务。
除了这四种默认的拒绝策略外还可以通过实现RejectedExecutionHandler接口来自定义任务拒绝策略。通过实现该接口可以定义自己的拒绝策略逻辑例如将被拒绝的任务记录下来或将其放入其他队列中等。然后可以将自定义的拒绝策略传递给线程
在自定义线程池中我们需要掌握好自定义过程中的七个参数的意义。
线程池多大才算合适
线程池大小的计算是有计算公式的在介绍计算公式之前我们要先讲解一下什么是最大并行数 最大并行数指的是在给定的系统环境下同时执行的最大线程或任务数。 线程池大小计算公式
1.CPU密集型运算 在CPU密集型运算中任务主要是由CPU执行涉及较少的I/O操作。在这种情况下线程池的大小可以通过以下公式计算
最大并行数1
2.I/O密集型运算 在I/O密集型运算中任务涉及大量的I/O操作例如读取文件、网络通信等。在这种情况下由于任务执行时间中有很多时间被阻塞在I/O等待上可以通过以下公式计算线程池的大小
Nthreads Ncpu * Ucpu * (1 (W/C))Nthreads 是线程池中的线程数。Ncpu 是计算机中的CPU核心数。Ucpu 是期望的CPU利用率0 Ucpu 1。它表示期望的CPU工作时间与总时间的比例。W/C 通常设置为较大的值以便在I/O等待期间可以让CPU执行其他任务。
在I/O密集型任务中通过增加线程池的大小可以更好地利用I/O等待的时间提高整体的并发性能。然而过量的线程数也会增加上下文切换的开销因此需要根据实
总结 今天我们学习了线程池的使用学习了调用库类实现线程池以及自定义线程池。而多线程的内容其实并没有介绍完毕我们将会在后面详细的介绍线程中比较重要的乐观锁以及悲观锁还有大名鼎鼎的CAS算法。
如果我的内容对你有帮助请点赞评论收藏。创作不易大家的支持就是我坚持下去的动力