多线程代码案例之线程池

在这里插入图片描述

作者简介: zoro-1,目前大二,正在学习Java,数据结构,javaee等
作者主页: zoro-1的主页
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

创建线程池

public class PoolText {public static void main(String[] args) {ExecutorService executorService= Executors.newFixedThreadPool(2);executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("任务1 "+Thread.currentThread());}});executorService.submit(new Runnable() {@Overridepublic void run() {System.out.println("任务2 "+Thread.currentThread());}});}
}

一共有两大种创建线程池的方式

ThreadPoolExcutor类创建线程池

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) 
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)

以上四种方法都是大同小异,这里我们挑选参数最多的进行讲解

public ThreadPoolExecutor(// 线程池核心线程数int corePoolSize, // 线程池最大数int maximumPoolSize, // 空闲线程存活时间long keepAliveTime,  // 时间单位TimeUnit unit,// 线程池所使用的阻塞队列BlockingQueue<Runnable> workQueue,// 线程池创建线程使用的工厂ThreadFactory threadFactory,// 线程池对拒绝任务的处理策略RejectedExecutionHandler handler)}

将线程池比作一个公司,当这个公司不忙时是10个员工(corePoolSize),忙碌起来就需要招实习生,假设招来5个实习生(maximumPoolSize=5+10),当公司不忙时,实习生就空闲下来了,这时就要裁掉实习生,但是是当实习生空闲到一定时间才裁掉,假设实习生空闲10小时就要裁掉他们(keepAliveTime=10,unit=h)
而这里的阻塞队列负责的就是存任务,threadFactory就是将创建线程对象的任务交给工厂类(将工厂方法(使用普通方法将构造方法封装起来)放进类),而这里的handler就是当队列满的时候如何处理新的任务加进来的情况。

这里为什么要用阻塞队列?

阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。当队列中有任务时才唤醒对应线程从队列中取出消息进行执行。使得在线程不至于一直占用cpu资源。

处理决策

ThreadPoolExecutor是Java中的线程池实现类,它提供了四种处理策略:

  1. AbortPolicy(默认策略):当线程池无法容纳新的任务时,会抛出RejectedExecutionException异常。

  2. CallerRunsPolicy:当线程池无法容纳新的任务时,任务会退回给调用者执行,这样调用者就会阻塞。

  3. DiscardOldestPolicy:当线程池无法容纳新的任务时,会丢弃队列中最老的一个任务,然后尝试再次提交新任务。

  4. DiscardPolicy:当线程池无法容纳新的任务时,会直接丢弃任务,不做任何处理。

这些处理策略可以在创建ThreadPoolExecutor对象时通过参数设置。如果没有显式地指定,默认使用AbortPolicy策略。根据具体的业务需求,可以选择适合的处理策略。

Executors类创建线程池

  1. newFixedThreadPool(int nThreads):创建一个固定大小的线程池,该线程池中的线程数始终为nThreads。

  2. newCachedThreadPool():创建一个可缓存的线程池,该线程池中的线程数根据需要动态增加或减少,空闲线程会被保留60秒。

  3. newSingleThreadExecutor():创建一个只有一个线程的线程池,该线程池保证所有任务按照提交顺序依次执行。

  4. newScheduledThreadPool(int corePoolSize):创建一个定时任务线程池,该线程池可以定期执行任务或延迟执行任务。

这些方法返回的都是ExecutorService接口的实例,使用execute()方法来提交任务给线程池执行。

手搓一个线程池

过程:
1.创建一个构造方法,创建指定线程数,并让这些线程执行任务
2.有一个阻塞队列用来添加任务
3.创建一个submit方法添加新任务

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;class MyPool{private List<Thread> list=new ArrayList<>();private BlockingQueue<Runnable> blockingDeque=new ArrayBlockingQueue<>(1000);//这里开启n个线程,这些线程不断的从阻塞队列的队首获取任务,一直执行public MyPool(int n) throws InterruptedException {for(int i=0;i<n;i++){Thread t=new Thread(()->{while (true){Runnable runnable= null;try {runnable = blockingDeque.take();} catch (InterruptedException e) {throw new RuntimeException(e);}runnable.run();}});list.add(t);t.start();}}public  void submit(Runnable runnable) throws InterruptedException {blockingDeque.put(runnable);}
}
public class pool {public static void main(String[] args) throws InterruptedException {MyPool myPool=new MyPool(5);for(int i=0;i<1000;i++){int n=i;//因为这里是变量捕获语法变量是事实不可变的或final修饰这里可以采取每次都重新定义一个新的变量n(小技巧)myPool.submit(new Runnable() {@Overridepublic void run() {System.out.println("当前线程是"+Thread.currentThread().getName()+"完成任务为"+n);}});}}
}
                         今天的分享到这里就结束了,感谢大家支持

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/443071.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】System V 共享内存

文章目录 一、System V共享内存的原理共享内存的内核数据结构 二、共享内存的使用1. 创建shmget()系统调用创建shm在命令行中查询共享内存 2. 释放使用命令释放共享内存资源使用shmctl释放共享内存资源 3. 关联4. 去关联 三、用共享内存实现server&client通信 一、System V…

(1)SpringBoot学习——芋道源码

Spring Boot 的快速入门 一.、概述 使用 Spring Boot 可以很容易地创建出能直接运行的独立的、生产级别的基于 Spring 的应用。 二、快速入门 2.1 创建 Maven 项目 打开 IDEA&#xff0c;点击菜单 File -> New -> Project.来创建项目选择 Maven 类型&#xff0c;点击「…

一分钟在SpringBoot项目中使用EMQ

先展示最终的结果: 生产者端: RestController RequiredArgsConstructor public class TestController {private final MqttProducer mqttProducer;GetMapping("/test")public String test() {User build User.builder().age(100).sex(1).address("世界潍坊渤…

linux解决访问/下载github连接超时或下载慢的问题

问题 我这里是树莓派从github下载资源出现无法连接&#xff0c;连接超时的问题&#xff0c;如下所示解决方式 修改/etc/hosts文件 例&#xff1a; sudo nano /etc/hosts #添加如下 192.30.255.112 github.com git 185.31.16.184 github.global.ssl.fastly.net这里以树莓派为…

【C++】构造函数和析构函数详解

目录 前言 类中的六个默认成员函数 构造函数 概念 特性 析构函数 概念 特性&#xff1a; 前言 类中的六个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编…

IT运维如何帮助企业降本增效?

IT监控运维管理技术发展应用和趋势 1、智能运维 随着人工智能和大数据技术的发展&#xff0c;智能运维将成为IT监控运维管理的重要趋势。通过利用机器学习、深度学习等技术&#xff0c;实现对IT系统的自动化监控、故障预测和智能维护&#xff0c;提高运维效率和质量。 2、容…

代码随想录——贪心算法

系列文章目录 代码随想录——回溯 代码随想录——贪心算法 文章目录 系列文章目录概述简单分发饼干摆动序列***最大子数组和买卖股票的最佳时机 II跳跃游戏跳跃游戏IIK次取反后最大化的数组和加油站***分发糖果柠檬水找零***根据身高重建队列全排列II 棋盘问题N皇后***解数独 …

C++ 数论相关题目 台阶-Nim游戏

现在&#xff0c;有一个 n 级台阶的楼梯&#xff0c;每级台阶上都有若干个石子&#xff0c;其中第 i 级台阶上有 ai 个石子(i≥1 )。 两位玩家轮流操作&#xff0c;每次操作可以从任意一级台阶上拿若干个石子放到下一级台阶中&#xff08;不能不拿&#xff09;。 已经拿到地面…

防御第五次作业-防火墙综合实验(nat、双机热备、带宽、选路)

目录 拓扑图 要求 1 2 3 4 5 办公区上网用户限制流量不超过60M 销售部限流 6 7 拓扑图 说明&#xff1a;基本配置完成。所有设备均可出网。 要求 1.办公区设备可以通过电信和移动两条链路上网&#xff0c;且需要保留一个公网ip不能用来转换。 2.分公司设备可以通…

flink cdc,standalone模式下,任务运行一段时间taskmanager挂掉

在使用flink cdc&#xff0c;配置任务运行&#xff0c;过了几天后&#xff0c;任务无故取消&#xff0c;超时&#xff0c;导致taskmanager挂掉&#xff0c;相关异常如下&#xff1a; 异常1&#xff1a; did not react to cancelling signal interrupting; it is stuck for 30 s…

快速排序|超详细讲解|入门深入学习排序算法

快速排序介绍 快速排序(Quick Sort)使用分治法策略。 它的基本思想是&#xff1a;选择一个基准数&#xff0c;通过一趟排序将要排序的数据分割成独立的两部分&#xff1b;其中一部分的所有数据都比另外一部分的所有数据都要小。然后&#xff0c;再按此方法对这两部分数据分别进…

第九节HarmonyOS 常用基础组件23-Menu、MenuItem、MenuItemGroup

1、描述 Menu&#xff1a;以垂直列表形式显示的菜单。 MenuItem&#xff1a;用来展示菜单Menu中具体的item菜单项。 MenuItemGroup&#xff1a;该组件用来展示菜单MenuItem的分组。 2、子组件 Menu&#xff1a;包含MenuItem、MenuItemGroup子组件。 MenuItem&#xff1a;…