多线程(七)线程池

news/2024/11/29 6:29:34/

线程池,又是一个池,我们已经见识过很多池了:

数据库连接池、字符串常量池....

那我们这个线程池又是个啥呢?

我们提前将线程准备好,需要用的时候直接取,不需要用的时候,在直接还回去。

这样就不需要去从系统中申请了。

这样做,最大的好处就是减少每次启动、销毁线程的损耗

池的目的就是为了提高效率。

为什么需要提高效率呢?

虽然线程对比于进程较为轻量,但是频繁的创建、销毁依旧开销很大。

为什么这也可以提升效率呢?

从线程池拿线程,时纯粹的用户态操作;

而从系统创建线程涉及到了用户态和内核态之间的切换;

真正的创建线程是要在内核态完成的。

举个栗子(🌰)

我们现在突然需要一个线程,我们直接可以从用户台中(前提是用户态中有线程);但是如果我们要从内核态中拿到这个线程,确实可以拿到,但是在拿的这个过程中内核还做了其他的很多事...

一旦涉及到了内核态时间就是不可控的。

用户态和内核态是操作系统中的基本概念:

内核态(Kernel Mode):运行操作系统程序,操作硬件

用户态(User Mode):运行用户程序

我们简单的理解:

一个操作系统  =  内核  +  配套的应用程序 

标准库中的线程池

我们先来写一个jdk 提供的线程池:

 public static void main(String[] args) {ExecutorService pool = Executors.newFixedThreadPool(10);pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello");}});}

这里并不是使用 ThreadPool 而是使用 ExcutorService ; 

工厂模式的概念:

主要就是用来填构造方法的坑的。

这里的工厂模式主要来自于ThreadPoolExecutor 这个原装线程池对象,上述工厂类是对这个原生类进行了封装,只要了解清楚这个类,其他工厂类就简单了。

我们再来重点解释一下 这几个参数的含义:

 

标准库中的四种拒绝策略:

拒绝策略类型说明
1 ThreadPoolExecutor.AbortPolicy默认拒绝策略,拒绝任务并抛出任务
2 ThreadPoolExecutor.DiscardPolicy 使用调用线程直接运行任务
3ThreadPoolExecutor.DiscardOldestPolicy  直接拒绝任务,不抛出错误
4ThreadPoolExecutor.CallerRunsPolicy 触发拒绝策略,只要还有任务新增,一直会丢弃阻塞队列的最老的任务,并将新的任务加入

接下来我们手动实现一个线程池:

实现线程池

看代码:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;public class MyThreadPool {private BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();// 作用类似于生产者,给线程添加任务public void submit(Runnable runnable) throws InterruptedException {queue.put(runnable);}// 此处实现一个固定线程数的线程池public MyThreadPool(int n) {// 循环内有一个工作线程// 类似于生产者,每次去取和执行这个任务for (int i = 0; i < n; i++) {//Thread t = new Thread(() -> {try {while (true) {Runnable runnable = queue.take();runnable.run();}} catch (InterruptedException e) {e.printStackTrace();}});t.start();}}public static void main(String[] args) throws InterruptedException {MyThreadPool pool = new MyThreadPool(10);for (int i = 0; i < 1000; i++) {int number = i;pool.submit(new Runnable() {@Overridepublic void run() {System.out.println("hello " + number);}});}}
}

我们来跑一跑:

 因为线程的调度是无序的,虽然是 按顺序添加的,但是结果仍然是个无序的状态。

线程池的优点:

1. 降低资源的消耗,利用已创建的线程,降低了线程的不断地创建和销毁的资源浪费
2. 提高相应小笼包,每次都是直接使用已经创建好的线程,不必去等待线程的创建
3. 提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,监控和调优。

多线程的基础也就到这结束了,这六章属于是面试常考,工作中常用的,我们接下来还有进阶部分,这属于锦上添花的,能记下来最好。


http://www.ppmy.cn/news/39200.html

相关文章

重磅发布!百分点科技正式发布数据科学基础平台DeepMatrix

‍数据智能产业创新服务媒体——聚焦数智 改变商业3月30日&#xff0c;由百分点科技主办的“2023数据科学峰会”在北京金隅智造工场科技秀场成功召开。此次大会以“数据进阶”为主题&#xff0c;邀请权威专家学者以科学视角和全球视野解读数据科学、数字政府建设及数字化业务&…

RouterBootUI组件库(Vue3+TS+Scss/Sass+Vite+Lerna+Rollup)

RouterBootUI组件库&#xff08;Vue3TSScss/SassViteLernaRollup&#xff09;RouterBootUI组件库&#xff08;Vue3TSScss/SassViteLernaRollup&#xff09;前言技术选项参考官网项目地址项目构建1. 安装Lerna2.lerna初始化文件夹3.配置lerna文件lerna.jsonpackage.json4.安装依…

从零开始实现一个C++高性能服务器框架----线程模块

此项目是根据sylar框架实现&#xff0c;是从零开始重写sylar&#xff0c;也是对sylar丰富与完善 项目地址&#xff1a;https://gitee.com/lzhiqiang1999/server-framework 简介 项目介绍&#xff1a;实现了一个基于协程的服务器框架&#xff0c;支持多线程、多协程协同调度&am…

界面控件DevExtreme v23.1抢先体验,增强的UI/UX自定义功能!

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序&#xff0c;该套件附带功能齐…

从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala

从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala 前言 【本文适合有一定计算机基础/半年工作经验的读者食用。立个Flg&#xff0c;愿天下不再有肤浅的SQL Boy】 谈到大数据开发&#xff0c;占据绝大多数人口的就是SQL Boy&#xff0c;不接受反驳&#xff0c;毕竟大…

【go 定时调度框架】你知道几种go语言定时调度框架?

Go语言中有很多类似Python apscheduler 的定时调度框架&#xff0c;其中比较流行的有以下几个&#xff1a; cron: 一个基于Cron表达式的定时任务库&#xff0c;可以精确到秒级。它提供了简单易用的API来定义和管理定时任务&#xff0c;支持任务暂停、恢复、删除等操作&#xf…

FFmpeg添加字幕的详细操作

FFmpeg添加字幕的详细操作 在视频中添加字幕可以使视频更具可读性&#xff0c;并为观众提供更好的观看体验&#xff0c;这在多语种内容中尤为重要。FFmpeg是一个流行的开源视频处理工具&#xff0c;它可以被用来给视频添加字幕。本文将介绍FFmpeg集成libass的编译流程&#xf…

2023年第四届世界蜂疗大会将于7月25日至27日在重庆武隆举办

【39蜂疗网】记者 讯 从世界蜂疗大会智库专家筹备会上获悉&#xff0c;2023年第四届世界蜂疗大会将于7月25日至27日在重庆武隆举办&#xff1b;本次大会以“加速推进新时代蜂疗事业高质量发展”为主题&#xff0c;将深刻把握全球中医蜂疗产业发展趋势。将对后疫情时代蜂疗行业高…