当前位置: 首页 > news >正文

JavaSE-线程池(1)- 线程池概念

JavaSE-线程池(1)- 线程池概念

前提

使用多线程可以并发处理任务,提高程序执行效率。但同时创建和销毁线程会消耗操作系统资源,虽然java 使用线程的方式有多种,但是在实际使用过程中并不建议使用 new Thread 的方式手动创建线程。

线程池概念

线程池可以理解成一个存放线程的容器,当需要使用线程处理任务时从线程池中取,而并非直接创建一个线程

使用线程池的优势

  1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  2. 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
  3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

来自 《Java 并发编程的艺术》

线程池相关接口以及类

Runnable

可以理解成一个不需要获取返回结果的任务

@FunctionalInterface
public interface Runnable {public abstract void run();
}

Callable

类似于 Runnable ,是一个有返回结果的任务

@FunctionalInterface
public interface Callable<V> {/*** Computes a result, or throws an exception if unable to do so.** @return computed result* @throws Exception if unable to compute a result*/V call() throws Exception;
}

Future

异步任务提交后使用 Future 接收,从 Future get 方法可以获取异步任务的返回值

public interface Future<V> {boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled();boolean isDone();V get() throws InterruptedException, ExecutionException;V get(long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}

RunnableFuture

Runnable 和 Future 的结合体

public interface RunnableFuture<V> extends Runnable, Future<V> {/*** Sets this Future to the result of its computation* unless it has been cancelled.*/void run();
}

FutureTask

RunnableFuture 接口的实现类

public class FutureTask<V> implements RunnableFuture<V> {
}

使用demo:

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class FutureTaskTest {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask futureTask = new FutureTask(() -> {Thread.sleep(1000);return 100;});new Thread(futureTask).start();System.out.println(futureTask.get());}
}

Executor

执行器,用来执行 Runnable 任务,通过实现 Executor 接口可以自定义任务的执行方式,比方使用线程池来执行任务,避免使用 new Thread 的方式来执行

public interface Executor {/*** 执行方法,执行一个具体的 Runnable 任务*/void execute(Runnable command);
}

ExecutorService

继承自 Executor ,提供更多的方法,实现线程池的类一般继承这个接口

public interface ExecutorService extends Executor {/*** 关闭执行器,但是会等待已经提交的任务执行完成,不再接收新的任务*/void shutdown();/*** 尝试停止所有正在执行的任务,不再接收新的任务*/List<Runnable> shutdownNow();/***判断执行器是否关闭,如果此执行器已关闭,则返回true。*/boolean isShutdown();/*** 如果关闭后(调用 shutdown 或 shutdownNow 方法)所有任务都已完成,则返回true。* 请注意,除非首先调用shutdown或shutdownNow,否则isTerminated       永远不会为true。*/boolean isTerminated();/*** Blocks until all tasks have completed execution after a shutdown* request, or the timeout occurs, or the current thread is* interrupted, whichever happens first.*/boolean awaitTermination(long timeout, TimeUnit unit)throws InterruptedException;/*** 提交一个有返回值的任务并使用 Future 接收*/<T> Future<T> submit(Callable<T> task);/*** Submits a Runnable task for execution and returns a Future* representing that task. The Future's {@code get} method will* return the given result upon successful completion.*/<T> Future<T> submit(Runnable task, T result);/*** 提交任务并使用 Future 接收*/Future<?> submit(Runnable task);/*** Executes the given tasks, returning a list of Futures holding* their status and results when all complete.* {@link Future#isDone} is {@code true} for each* element of the returned list.* Note that a <em>completed</em> task could have* terminated either normally or by throwing an exception.* The results of this method are undefined if the given* collection is modified while this operation is in progress.*/<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)throws InterruptedException;/*** Executes the given tasks, returning a list of Futures holding* their status and results* when all complete or the timeout expires, whichever happens first.* {@link Future#isDone} is {@code true} for each* element of the returned list.* Upon return, tasks that have not completed are cancelled.* Note that a <em>completed</em> task could have* terminated either normally or by throwing an exception.* The results of this method are undefined if the given* collection is modified while this operation is in progress.*/<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException;/*** Executes the given tasks, returning the result* of one that has completed successfully (i.e., without throwing* an exception), if any do. Upon normal or exceptional return,* tasks that have not completed are cancelled.* The results of this method are undefined if the given* collection is modified while this operation is in progress.*/<T> T invokeAny(Collection<? extends Callable<T>> tasks)throws InterruptedException, ExecutionException;/*** Executes the given tasks, returning the result* of one that has completed successfully (i.e., without throwing* an exception), if any do before the given timeout elapses.* Upon normal or exceptional return, tasks that have not* completed are cancelled.* The results of this method are undefined if the given* collection is modified while this operation is in progress.*<T> T invokeAny(Collection<? extends Callable<T>> tasks,long timeout, TimeUnit unit)throws InterruptedException, ExecutionException, TimeoutException;
}

AbstractExecutorService

public abstract class AbstractExecutorService implements ExecutorService {
}

实现 ExecutorService 接口,提供ExecutorService执行方法的默认实现

ThreadPoolExecutor

public class ThreadPoolExecutor extends AbstractExecutorService {
}

线程池的具体实现类,继承自 AbstractExecutorService

类结构图:

ThreadPoolExecutor 使用方法

可以使用工具类 Executors 提供的方法创建线程池,比如:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ExecutorServiceTest1 {static class MyTask implements Runnable {private int i;public MyTask(int i) {this.i = i;}@Overridepublic void run() {try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread() + " 任务" + i);}}public static void main(String[] args) {ExecutorService executorService = Executors.newFixedThreadPool(2);for (int i = 1; i <= 10; i++) {executorService.execute(new MyTask(i));}executorService.shutdown();}
}

以上 Executors.newFixedThreadPool 方法创建了一个拥有固定线程数的线城池

public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}

执行结果:

Thread[pool-1-thread-1,5,main] 任务1
Thread[pool-1-thread-2,5,main] 任务2
Thread[pool-1-thread-2,5,main] 任务4
Thread[pool-1-thread-1,5,main] 任务3
Thread[pool-1-thread-1,5,main] 任务6
Thread[pool-1-thread-2,5,main] 任务5
Thread[pool-1-thread-2,5,main] 任务8
Thread[pool-1-thread-1,5,main] 任务7
Thread[pool-1-thread-2,5,main] 任务9
Thread[pool-1-thread-1,5,main] 任务10

通过结果可以看出,10个任务都是由两个线程执行的,由于这两个线程一次只能处理两个任务,其他任务只有在线程空闲时才能被处理,实际上线程池不仅维护了一组线程的引用,还维护了这组任务,而任务则是放在队列中,即上文的 LinkedBlockingQueue 参数

参考:
https://blog.csdn.net/qq_36881887/article/details/125707550
https://www.mianshigee.com/note/detail/20134hnk/

相关文章:

JavaSE-线程池(1)- 线程池概念

JavaSE-线程池&#xff08;1&#xff09;- 线程池概念 前提 使用多线程可以并发处理任务&#xff0c;提高程序执行效率。但同时创建和销毁线程会消耗操作系统资源&#xff0c;虽然java 使用线程的方式有多种&#xff0c;但是在实际使用过程中并不建议使用 new Thread 的方式手…...

开源代码的寿命为何只有1年?

说实话&#xff0c;如果古希腊的西西弗斯是一个在2016年编写开源代码的开发者&#xff0c;那他会有宾至如归的感觉。著名的西西弗斯处罚&#xff0c;是神话流传下来的&#xff0c;他被迫推一块巨大的石头上山&#xff0c;当登顶之后&#xff0c;只能眼睁睁看着它滚下去&#xf…...

完善登录功能--过滤器的使用

系列文章目录 Spring Boot读取配置文件内容的三种方式 Spring Boot自动配置–如何切换内置Web服务器 SpringBoot项目部署 上述为该系列部分文章&#xff0c;想了解更多可看我博客主页哦&#xff01; 文章目录系列文章目录前言一、创建自定义过滤器LoginCheckFilter二、在启动类…...

CSS基础:属性和关系选择器

字体属性 color 文本颜色 div{ color:red;} div{ color:#ff0000;} div{ color:rgb(255,0,0);} div{ color:rgba(255,0,0,.5);}font-size 文本大小 h1 {font-size:40px;} h2 {font-size:30px;} p {font-size:14px;}注意&#xff1a;chrome浏览器接受最小字体是12px font-we…...

设计模式:原型模式解决对象创建成本大问题

一、问题场景 现在有一只猫tom&#xff0c;姓名为: tom, 年龄为&#xff1a;1&#xff0c;颜色为&#xff1a;白色&#xff0c;请编写程序创建和tom猫属性完全相同的10只猫。 二、传统解决方案 public class Cat {private String name;private int age;private String color;…...

驱动开发(二)

一、驱动流程 驱动需要以下几个步骤才能完成对硬件的访问和操作&#xff1a; 模块加载函数 module_init注册主次设备号 <应用程序通过设备号找到设备>驱动设备文件 <应用程序访问驱动的方式> 1、手动创建 &#xff08;mknod&#xff09;2、程序自动创建file_oper…...

《狂飙》大结局,这22句经典台词值得细品

最近爆火的热播剧《狂飙》大家都看了吗&#xff1f; 剧情紧凑、演技炸裂、豆瓣评分9.0&#xff0c;可以说是开年评分最高的一部国产剧。 ​ 虽然大结局了。 里面有很多经典台词&#xff0c;值得每个人细细品味。 01 这世界不缺梦想 有本事你就去实现它 02 你这么善良 怎么跟坏…...

【计算机网络期末复习】第二章 物理层

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4e3;专栏定位&#xff1a;为想复习学校计算机网络课程的同学提供重点大纲&#xff0c;帮助大家渡过期末考~ &#x1f4da;专栏地址&#xff1a; ❤️如果有收获的话&#xff0c;欢迎点…...

多核异构核间通信-mailbox/RPMsg 介绍及实验

1. 多核异构核间通信 由于MP157是一款多核异构的芯片&#xff0c;其中既包含的高性能的A7核及实时性强的M4内核&#xff0c;那么这两种处理器在工作时&#xff0c;怎么互相协调配合呢&#xff1f; 这就涉及到了核间通信的概念了。 IPCC (inter-processor communication contr…...

【Rust日报】2023-02-11 从头开始构建云数据库 RisingWave - 为什么我们从 C++ 转向 Rust...

GTK4发布v0.60gtk4-rs代码库包含GTK4的Rust crates。还有个庞大的GObject库生态系统&#xff0c;其中许多库基于gtk-rs中包含的Rust绑定工具。 特别是&#xff1a;gtk-rs-core&#xff0c;一些核心库的绑定&#xff0c;例如 glib、gio、pango、graphenegstreamer-rs&#xff0c…...

Linux驱动开发(一)

linux驱动学习记录 一、背景 在开始学习我的linux驱动之旅之前&#xff0c;先提一下题外话&#xff0c;我是一个c语言应用层开发工作人员&#xff0c;在工作当中往往会和硬件直接进行数据的交互&#xff0c;往往遇到数据不通的情况&#xff0c;常常难以定位&#xff0c;而恰巧…...

Spring MVC 之返回数据(静态页面、非静态页面、JSON对象、请求转发与请求重定向)

文章目录1. 默认情况下返回静态页面2. 返回一个非静态页面的数据2.1 ResponseBody 返回页面内容2.2 RestController ResponseBody Controller3. 实现登录功能&#xff0c;返回 JSON 对象3.1 前端使⽤ ajax&#xff0c;后端返回 json 给前端3.2 前端发送 JSON 的标准格式4. 请…...

leetcode-每日一题-2335(简单,贪心)

自己打表看一下过程就可以发现&#xff0c;其实就是每次选两个大的进行--之后秒数加1即可现有一台饮水机&#xff0c;可以制备冷水、温水和热水。每秒钟&#xff0c;可以装满 2 杯 不同 类型的水或者 1 杯任意类型的水。给你一个下标从 0 开始、长度为 3 的整数数组 amount &am…...

Verilog语法之数学函数

Verilog-2005支持一些简单的数学函数&#xff0c;其参数的数据类型只能是integer和real型。 Integer型数学函数 $clog2是一个以2为底的对数函数&#xff0c;其结果向上取整&#xff0c;返回值典型的格式&#xff1a; integer result; result $clog2(n); 最典型的应用就是通过…...

【手撕面试题】JavaScript(高频知识点一)

目录 面试官&#xff1a;请你简述 var、let、const 三者之间的区别&#xff1f; 面试官&#xff1a;请你谈谈对深拷贝与浅拷贝的理解 面试官&#xff1a;输入URL的那一瞬间浏览器做了什么&#xff1f; 面试官&#xff1a;说一说cookie sessionStorage localStorage 区别&am…...

如何用PHP实现消息推送

什么是消息推送 通过服务器自动推送消息到客户端(浏览器&#xff0c;APP&#xff0c;微信)的应用技术。 2. 为什么要使用消息推送技术 通常情况下都是用户发送请求浏览器显示用户需要的信息。推送技术通过自动传送信息给用户&#xff0c;来减少用于网络上搜索的时间。它根据…...

电子学会2020年6月青少年软件编程(图形化)等级考试试卷(四级)答案解析

青少年软件编程&#xff08;Scratch&#xff09;等级考试试卷&#xff08;四级A卷&#xff09; 分数&#xff1a;100.00 题数&#xff1a;30 一、单选题&#xff08;共15题&#xff0c;每题2分&#xff0c;共30分&#xff09; 1. 执行下图程序后&#xff0c;“花名…...

DaVinci:调色版本

调色版本 Grade Version记录着片段的全部调色信息。将一种调色风格或效果&#xff0c;保存为一个调色版本&#xff0c;从而可在多个调色版本之间查看、比较、挑选或者渲染输出。调色版本类型本地版本Local Versions在没有创建新的调色版本之前&#xff0c;片段的调色信息默认记…...

【C++初阶】十二、STL---反向迭代器的实现

目录 一、反向迭代器 二、反向迭代器的实现 一、反向迭代器 之前的模拟实现vector、list 的时候&#xff0c;这些都是实现了正向迭代器&#xff0c;反向迭代器都没有实现&#xff0c;这里就要实现反向迭代器 反向迭代器也是适配器&#xff08;配接器&#xff09;的一种&#…...

day 43|● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

1049. 最后一块石头的重量 II 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结果…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...