从零学Java 线程池

Java 线程池

文章目录

  • Java 线程池
    • 1 线程池概念
      • 1.1 现有问题
      • 1.2 线程池
    • 2 线程池原理
    • 3 如何使用线程池
      • 3.1 获取线程池
    • 4 创建线程的第四种方式

1 线程池概念

1.1 现有问题

  • 线程是宝贵的内存资源、单个线程约占1MB空间,过多分配易造成内存溢出。
  • 频繁的创建及销毁线程会增加虚拟机回收频率、资源开销,造成程序性能下降。

1.2 线程池

  • 线程容器,可设定线程分配的数量上限。
  • 将预先创建的线程对象存入池中,并重用线程池中的线程对象。
  • 避免频繁的创建和销毁。

2 线程池原理

在这里插入图片描述

将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。

3 如何使用线程池

3.1 获取线程池

常用的线程池接口和类(所在包java.util.concurrent):

  • Executor:线程池的顶级接口。
    • execute(); 执行任务
  • ExecutorService:线程池接口,可通过submit(Runnable task) 提交任务代码。
    • shutdown() 关闭线程池
    • isTerminated() 判断线程池中任务和线程是否已经执行完毕。
    • submit() 提交任务
  • Executors工厂类:通过此类可以获得一个线程池。
    • newFixedThreadPool(int nThreads) 获取固定数量的线程池。
      参数:指定线程池中线程的数量。
    • newCachedThreadPool() 获得动态数量的线程池,如不够则创建新的,无上限。

eg:

//1 创建固定数量的线程池
ExecutorService es = Executors.newFixedThreadPool(4);
//2 创建动态数量的线程池
ExecutorService es = Executors.newCachedThreadPool();
public class TestExecutors {public static void main(String[] args) {//1.1 创建固定数量的线程池//ExecutorService es = Executors.newFixedThreadPool(4);//1.2 创建动态数量的线程池ExecutorService es = Executors.newCachedThreadPool();//2 添加任务Runnable ticket = new Runnable() {private int count = 1000;@Overridepublic void run() {while (true) {synchronized (this) {if (count<=0) {break;}System.out.println(Thread.currentThread().getName()+"卖了第"+count+"张票");count--;}}}};for (int i = 0; i < 4; i++) {//提交任务es.submit(ticket);}//3 关闭线程池es.shutdown();}
}

eg:

//3 创建单线程线程池, 只有一个线程的线程池
public class TestSingThread {public static void main(String[] args) {//3 创建单线程线程池, 只有一个线程的线程池ExecutorService es = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {es.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"...");}});}es.shutdown();}
}

eg:

//4 创建调度线程池, 实现周期执行和延迟执行
public class TestScheduleThread {public static void main(String[] args) {//4 创建调度线程池, 实现周期执行和延迟执行//周期执行: 间隔指定时间执行一次, 不能关闭线程ScheduledExecutorService es = Executors.newScheduledThreadPool(1);es.scheduleAtFixedRate(new Runnable() {int num = 0;@Overridepublic void run() {System.out.println(new Date()+"..."+num);num++;if (num == 10) {es.shutdown();}}},0,1000, TimeUnit.MILLISECONDS);//延迟执行: 延迟一定时间执行es.schedule(new Runnable() {@Overridepublic void run() {System.out.println(new Date());}},3000, TimeUnit.MILLISECONDS);es.shutdown();}
}

eg:

//5 工作窃取线程池
public class TestWorkStealingPool {public static void main(String[] args) {//5 工作窃取线程池//5.1 工作窃取线程池中的都属于后台线程//5.2 每一个线程都有自己的双端队列, 队头和队尾都可以加入和删除元素//5.3 自己线程的队列中任务执行完后, 会去别的线程队列的队尾窃取一个任务执行//默认使用CPU内核个数作为线程个数ExecutorService es = Executors.newWorkStealingPool();for (int i = 0; i < 10; i++) {es.submit(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"...");}});}es.shutdown();//阻止主线程结束while (!es.isTerminated()); //判断线程池中的任务和线程是否执行完毕System.out.println("执行完毕");}
}

4 创建线程的第四种方式

实现 Callable 接口, 重写 call() 方法

  • JDK5加入,与Runnable接口类似,实现之后代表一个线程任务。
  • Callable具有泛型返回值、可以声明异常。

语法:

public interface Callable<V>{public V call() throws Exception;
}

Future接口

  • 概念:异步接收ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值。
  • 方法:V get()以阻塞形式等待Future中的异步处理结果(call()的返回值)

eg:

MyCallable:

public class MyCallable implements Callable<Integer> {@Overridepublic Integer call() throws Exception {int sum = 0;System.out.println(Thread.currentThread().getName()+"开始计算...");for (int i = 1; i <= 100; i++) {sum+=i;Thread.sleep(100);}System.out.println(Thread.currentThread().getName()+"结束计算...");return sum;}
}

Test:

public class Test {public static void main(String[] args) throws Exception{//1 创建可调用对象MyCallable mc = new MyCallable();//2 创建线程池(单线程线程池)ExecutorService es = Executors.newSingleThreadExecutor();//3 提交任务//Future: 表示线程将要执行完毕的结果Future<Integer> future = es.submit(mc);//4 获取结果(阻塞方法, 直到线程池中的任务执行完毕才返回)System.out.println("结果是:"+future.get());//5 关闭线程池es.shutdown();}
}

课堂案例

eg:

需求:使用两个线程,并发计算1~50、51~100的和,再进行汇总统计。
public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {//创建动态线程池ExecutorService es = Executors.newCachedThreadPool();//添加任务1Future<Integer> f1 = es.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 1; i <= 50 ; i++) {sum+=i;}return sum;}});//添加任务2Future<Integer> f2 = es.submit(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = 51; i <= 100 ; i++) {sum+=i;}return sum;}});//汇总System.out.println("结果为:"+(f1.get() + f2.get()));//关闭线程池es.shutdown();}
}

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

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

相关文章

Angular系列教程之自定义指令

文章目录 前言指令的基本概念在模板中使用指令总结 前言 在Angular中&#xff0c;指令是一种非常强大的工具&#xff0c;用于扩展HTML元素的功能和行为。它们允许我们创建可重用的组件&#xff0c;并在应用程序中的多个地方使用它们。本文将介绍Angular指令的基础知识&#xf…

AI工具(20240116):Copilot Pro,Fitten Code等

Copilot Pro Copilot Pro是微软推出的Copilot的付费增强版本,通过提供优先访问GPT-4等最新AI模型,大大提升用户的创造力和工作效率。该服务可与Microsoft 365订阅捆绑使用,支持在Word、Excel等Office应用内直接使用Copilot功能,帮助用户更快速地起草文档、电子邮件和演示文稿等…

自动驾驶轨迹规划之碰撞检测(二)

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.基于凸优化 2.具身足迹 3. ESDF 自动驾驶轨迹规划之碰撞检测&#xff08;一&#xff09;-CSDN博客 大家可以先阅读之前的博客 1.基于…

文件夹重命名技巧:如何避免过长名称带来的混乱,随机名称不再难

在日常生活和工作中&#xff0c;经常要管理大量的文件夹&#xff0c;有清晰、简洁的文件夹名称能大大提高工作效率。在工作的时候会遇到文件夹名称过长的问题&#xff0c;导致显示不完整、容易混淆&#xff0c;影响文件管理器的性能。下面一起来看云炫文件管理器如何批量重命名…

易模真人手办定制:好技术、好服务,共建消费者满意的新一代大众定制平台

随着我国人民精神文化与物质生活的不断升级&#xff0c;定制真人手办摆件的需求变得广泛&#xff0c;易模推出易模真人手办定制服务&#xff08;小程序&#xff09;&#xff0c;帮助市场合作伙伴能够以全线上、手机端形式为用户制作真人手办&#xff0c;“全线上”的内涵包括手…

鸿蒙应用开发学习:改进小鱼动画实现按键一直按下时控制小鱼移动和限制小鱼移出屏幕

一、前言 近期我在学习鸿蒙应用开发&#xff0c;跟着B站UP主黑马程序员的视频教程做了一个小鱼动画应用&#xff0c;UP主提供的小鱼动画源代码仅仅实现了移动组件的功能&#xff0c;还存在一些问题&#xff0c;如默认进入页面是竖屏而页面适合横屏显示&#xff1b;真机测试发现…

【SpringBoot篇】添加富文本编辑器操作

文章目录 &#x1f354;使用步骤⭐首先我们需要安装富文本编辑器⭐在<script>中引入富文本编辑器⭐富文本图片上传接口⭐初始化富文本编辑器⭐调用 初始化富文本编辑器的方法&#x1f388;新增&#x1f388;编辑&#x1f388;保存 ⭐添加按钮⭐实现viewEditor函数&#x…

视觉检测系统:工厂生产零部件的智能检测

在工厂的生产加工过程中&#xff0c;工业视觉检测系统被广泛应用&#xff0c;并且起着重要的作用。它能够对不同的零部件进行多功能的视觉检测&#xff0c;包括尺寸和外观的缺陷。随着制造业市场竞争越来越激烈&#xff0c;对产品质检效率的要求不断提高&#xff0c;传统的人工…

docker试用metabase

安装 docker run -d -p 3000:3000 --name metabase metabase/metabase 初始化 填写相关信息&#xff0c;不要选中文&#xff0c;翻译太生硬了&#xff0c;很多配置项例如聚合这样的词语看不懂&#xff0c;还不如换回英文。 数据查看 在数据源中选择 show editor 可以进行数据…

【不用找素材】ECS 游戏Demo制作教程(2) 1.16

一、知识点补充 1.工程内部 上一篇最后一步运行时&#xff0c;突然发现 变成52:1了&#xff0c;难道每次baking都是随机的&#xff1f; 破案了&#xff0c;52是index索引&#xff0c;1是version版本号 如果您在场景视图中看不到实体&#xff0c;但仍然可以在游戏视图中看到…

FPGA高端项目:12G-SDI 视频编解码,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的 GT 高速接口解决方案我目前已有的SDI编解码方案 3、详细设计方案设计框图UltraScale GTH 的SDI模式应用UltraScale GTH 基本结构参考时钟的选择和分配UltraScale GTH 发送和接收处理流程UltraScale GTH 发送接口UltraScale G…

数据结构与算法:归并排序

数据结构与算法&#xff1a;归并排序 归并思想递归法非递归 归并思想 在讲解归并排序前&#xff0c;我们先看到一个问题&#xff1a; 对于这样两个有序的数组&#xff0c;如何将它们合并为一个有序的数组&#xff1f; 在此我们处理这个问题的思路就是&#xff1a;开辟一个新的…

ATA-1222A宽带放大器在二极管测试中的应用有哪些

宽带放大器是一种用于放大高频信号的电子设备&#xff0c;它在二极管测试中有多种应用。下面安泰电子将介绍宽带放大器在二极管测试中的几种常见应用。 宽带放大器可以用于二极管参数测试。二极管是一种常见的半导体器件&#xff0c;有正向电压-电流特性和反向电压-电流特性。为…

【2.5操作系统】数据传输控制方式

目录 1.输入输出技术2.IO设备管理软件 1.输入输出技术 cpu控制&#xff08;主存/外设&#xff09;进行数据交互的过程。 中断处理操作过程&#xff1a; 例题一: 解析&#xff1a; 第一问&#xff1a;选D。中断需要cpu发送中断指令。 例题二&#xff1a; 解析&#xff1a; 第…

css-实现溢出内容转换为...格式

代码&#xff1a;overflow: hidden; text-overflow: ellipsis; overflow: hidden;//当容器中的内容超出容器的尺寸时&#xff0c;将隐藏超出部分而不显示滚动条。 display: -webkit-box;//使用WebKit引擎的浏览器&#xff08;如Chrome和Safari&#xff09;中&#xff0c;将容器…

AI数字人短视频变现项目:打造短视频运营变现新模式

随着社交媒体和短视频平台的兴起&#xff0c;越来越多的人开始关注如何将短视频变现。在这个时代&#xff0c;创新和科技成为了推动变现模式发展的关键。AI数字人作为一种全新的创新形式&#xff0c;正在迅速进入人们的视野。本文将介绍AI数字人短视频变现项目&#xff0c;以及…

Mysql 安装通过mysql installer安装+配置环境+连接可视化工具

注意&#xff1a;不适合纯小白&#xff0c;小白建议移步别的大佬MySQL详细安装教程 目录 注意&#xff1a;不适合纯小白&#xff0c;小白建议移步别的大佬MySQL详细安装教程 前言 准备工作 一、Mysql下载 二、MySQL installer 安装以及系统环境配置 三、检验MySQL 四、可…

抖店商家怎么维护好与达人关系?2024新版维护达人思路方法

我是王路飞。 当你找到达人给你带货&#xff0c;且积累了一些达人资源之后&#xff0c;就需要维护好与达人的关系了。 毕竟找达人带货玩法的好处&#xff0c;就是长期稳定&#xff0c;他能给你带来持续的收益。 那么抖店商家应该如何维护好与达人的关系呢&#xff1f; 这篇…

【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!

最近学习MetaGPT&#xff0c;用到了 pip install -e . 安装命令&#xff0c;这个安装命令是从源代码安装包。 从源代码安装包有几个好处&#xff1a; 包内的代码是可见的&#xff0c;是白盒&#xff0c;不是黑盒&#xff0c;可以直接在项目中看源码断点调试可以直接断到源码里…

HCIA——10实验:跨路由转发。静态路由、负载均衡、缺省路由、手工汇总、环回接口。空接口与路由黑洞、浮动静态。

学习目标&#xff1a; 跨路由转发、负载均衡、环回接口、手工汇总、缺省路由、空接口与路由黑洞、浮动静态 学习内容&#xff1a; 跨路由转发静态路由、负载均衡、缺省路由、手工汇总。环回接口空接口与路由黑洞、浮动静态 目录 学习目标&#xff1a; 学习内容&#xff1a…