创建线程池

news2024/12/26 23:33:12

如何创建线程池及处理相应任务

目录

  • 如何创建线程池及处理相应任务
    • 线程池定义
    • 解决的问题(需求)
    • 工作原理
    • 实现线程池创建示意图
    • 重要构造器
    • 创建线程池(ExecutorService)
    • 线程池任务处理
      • 常用API
      • 处理Runnable任务
      • 处理Callable任务
    • 使用工具类(Executors)创建线程池
      • 常用API
      • 应用案例
    • 拓展
      • 思考
      • 任务拒绝策略
    • 参考视频

线程池定义

线程池就是一个可以复用线程的技术,控制线程和任务的数量;线程池中线程长久存在

解决的问题(需求)

用户每发起一个请求,后台就需要创建一个新线程来处理,下次新任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能,甚至可能会引起系统瘫痪(宕机)

工作原理

  
在这里插入图片描述
  

实现线程池创建示意图

  
在这里插入图片描述
  

重要构造器

  
在这里插入图片描述
 
在这里插入图片描述
  

创建线程池(ExecutorService)

:通过实现类ThreadPoolExecutor()来创建。

package com.xie.thread.pool.demo;

import java.util.concurrent.*;

/**
 * 掌握线程池的创建 通过有参构造器创建
 * */
public class ThreadPoolTest {
    public static void main(String[] args) {
        /**
         * 创建线程池,其各参数具体含义:
         * 参数一:核心线程数量
         * 参数二:最大线程数量
         * 参数三:临时线程存活时间
         * 参数四:参数三的时间单位
         * 参数五:任务队列,此处用于 缓存 来自通信管道的任务的
         * 参数六:线程工厂,用于创建核心线程的
         * 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常
         * */
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}

线程池任务处理


常用API

  
在这里插入图片描述
  

:上面为处理处理Runnable任务的API


  
在这里插入图片描述
  

:上面为处理处理Callable任务的API


处理Runnable任务

Runnable任务类

package com.xie.thread.pool.task1.pojo;

/**
 * Runnable任务类,线程的任务对象模版
 * */
public class MyRunnable implements Runnable {
    /**
     * 执行任务区域(即run方法),描述所要执行的任务
     */
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "==> 输出666~~");
        /** 延迟,模拟业务执行耗时,为了便于观察 */
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试

package com.xie.thread.pool.task1;

import com.xie.thread.pool.task1.pojo.MyRunnable;
import java.util.concurrent.*;
/**
 * 处理Runnable任务
 * */
public class ThreadPoolTest {
    public static void main(String[] args) {
        /**
         * 创建线程池,其各参数具体含义:
         * 参数一:核心线程数量
         * 参数二:最大线程数量
         * 参数三:临时线程存活时间
         * 参数四:参数三的时间单位
         * 参数五:任务队列,此处用于 缓存 来自通信管道的任务的
         * 参数六:线程工厂,用于创建核心线程的
         * 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常
         * 注:线程池可以一直存活,除非主动去关闭
         * */
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        // 创建任务对象
        Runnable taskObject = new MyRunnable();
        // 把任务对象 交给 线程池执行。 注:线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
        pool.execute(taskObject);
        pool.execute(taskObject);
        pool.execute(taskObject);
        pool.execute(taskObject);
        pool.execute(taskObject);
        pool.execute(taskObject);
        pool.execute(taskObject);
        // 创建临时线程时机
        pool.execute(taskObject);
        pool.execute(taskObject); /** 对于此线程池来说,此第九个任务为极限值 */
        // 拒绝策略生效时机( 任务数量 > (5 + 4) )
        // pool.execute(taskObject);
        /** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */
        pool.shutdown();
        // 立即关闭线程池! 不管任务是否执行完毕!
        // pool.shutdownNow();
    }
}

处理Callable任务

Callable任务类

package com.xie.thread.pool.task2.pojo;

import java.util.concurrent.Callable;
/**
 * 让这个类实现callable接口  Callable任务类
 * */
public class MyCallable implements Callable<String> {
    private int n;
    public MyCallable(int n) {
        this.n = n;
    }

    /** 重写call方法 此为线程池后期调用的 任务方法(call方法) */
    @Override
    public String call() throws Exception {
        // 描述线程要执行的任务,返回线程执行完后的返回结果
        int sum = 0;
        for (int i = 0; i <= n; i++) {
            sum += i;
        }
        return Thread.currentThread().getName() + " 求出了 1-" + n + " 的和是:" + sum;
    }
}

测试

package com.xie.thread.pool.task2;

import com.xie.thread.pool.task2.pojo.MyCallable;
import java.util.concurrent.*;
/**
 * 处理Callable任务
 * Callable任务的最大特点:线程池处理任务完后,可以直接获取处理完任务后的结果
 * */
public class ThreadPoolTest {
    public static void main(String[] args) throws Exception {
        /**
         * 创建线程池,其各参数具体含义:
         * 参数一:核心线程数量
         * 参数二:最大线程数量
         * 参数三:临时线程存活时间
         * 参数四:参数三的时间单位
         * 参数五:任务队列,此处用于 缓存 来自通信管道的任务的
         * 参数六:线程工厂,用于创建核心线程的
         * 参数七:任务的拒绝策略,此处用到默认策略,直接拒绝的处理方案,当处理不了时,直接抛异常
         * 注:线程池可以一直存活,除非主动去关闭
         * */
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy());
        /** 使用已定义的有参构造器,创建任务对象 Callable对象 并交给线程池 处理
         *  并返回一个未来任务对象
         *  */
        Future<String> futureTask1 = pool.submit(new MyCallable(100));
        Future<String> futureTask2 = pool.submit(new MyCallable(200));
        Future<String> futureTask3 = pool.submit(new MyCallable(300));
        Future<String> futureTask4 = pool.submit(new MyCallable(400));
        Future<String> futureTask5 = pool.submit(new MyCallable(500));
        // 获取执行结果 并打印输出
        System.out.println(futureTask1.get());
        System.out.println(futureTask2.get());
        System.out.println(futureTask3.get());
        System.out.println(futureTask4.get());
        System.out.println(futureTask5.get());
        /** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */
        pool.shutdown();
        /** 测试 */
        // Callable my = new MyCallable(100);
        // System.out.println(my.call());
    }
}

使用工具类(Executors)创建线程池

常用API

  
在这里插入图片描述
  

应用案例

测试

package com.xie.thread.pool.tool;

import com.xie.thread.pool.task2.pojo.MyCallable;
import java.util.concurrent.*;
/**
 * --->通过工具类Executors创建线程池对象
 * Executors是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象
 *
 * final关键字(修饰符)作用:
 * 不能被继承,不能被修改???
 *
 * 注:此工具类中这些静态方法的底层,都是通过 线程池的实现类ThreadPoolExecutor 创建 的线程池对象。
 * 使用风险:
 * 大型并发系统环境中使用Executors如果不注意可能会出现系统风险
 * 所以,建议推荐使用 ThreadPoolExecutor()类 来创建线程池。
 *
 * 拓展知识:
 * 核心线程数量配置的参考策略:
 * 1,计算密集型的任务:核心线程数量 = CPU的核数 + 1
 * 2,IO密集型的任务:核心线程数量 = CPU核数 * 2
 * */
public class ThreadPoolTest {
    public static void main(String[] args) throws Exception {

        /** 通过工具类Executors方式 创建 线程池对象 新建固定线程数量的线程池(此处定义为3个) */
        final ExecutorService pool = Executors.newFixedThreadPool(3);
        /** 使用已定义的有参构造器,创建任务对象 Callable对象 并交给线程池 处理
         *  并返回一个未来任务对象
         *  */
        Future<String> futureTask1 = pool.submit(new MyCallable(100));
        Future<String> futureTask2 = pool.submit(new MyCallable(200));
        Future<String> futureTask3 = pool.submit(new MyCallable(300));
        Future<String> futureTask4 = pool.submit(new MyCallable(400));
        Future<String> futureTask5 = pool.submit(new MyCallable(500));
        // 获取执行结果 并打印输出
        System.out.println(futureTask1.get());
        System.out.println(futureTask2.get());
        System.out.println(futureTask3.get());
        System.out.println(futureTask4.get());
        System.out.println(futureTask5.get());
        /** 等着 线程池的任务 全部执行完毕后,再关闭线程池 */
        pool.shutdown();
    }
}

:此工具类中的这些静态方法的底层都是通过 线程池的 实现类ThreadPoolExecutor 来创建 线程池对象的。


拓展

思考

  
在这里插入图片描述
  

任务拒绝策略

  
在这里插入图片描述
  

参考视频

黑马磊哥


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

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

相关文章

桌面自动化工具总结

引言:产品经理提出桌面程序需要自动化的测试,避免繁琐的人肉点击。说干就干。 现有自动化工具是五花八门,我找了两个框架。 这两个框架都是基于微软的UIA 框架,链接地址 https://learn.microsoft.com/en-us/windows/win32/winauto/uiauto-providerportal?source=recommen…

以太网的MAC层

以太网的MAC层 一、硬件地址 ​ 局域网中&#xff0c;硬件地址又称物理地址或MAC地址&#xff08;因为用在MAC帧&#xff09;&#xff0c;它是局域网上每一台计算机中固化在适配器的ROM中的地址。 ​ 关于地址问题&#xff0c;有这样的定义&#xff1a;“名字指出我们所要寻…

【Spring】Bean作用域和生命周期

Bean作用域和生命周期 一. Bean 的作用域1. Bean 的 6 种作⽤域&#xff1a;①. singleton②. prototype③. request④. session⑤. application⑥. websocket单例作用域(singleton) VS 全局作⽤域(application) 2. 设置作用域 二. Spring 执行流程和 Bean 的生命周期1. Spring…

MySQL优化、锁、总结常见问题

慢 SQL 如何定位呢&#xff1f; 慢 SQL 的监控主要通过两个途径&#xff1a; 慢查询日志&#xff1a;开启 MySQL 的慢查询日志&#xff0c;再通过一些工具比如 mysqldumpslow 去分析对应的慢查询日志&#xff0c;当然现在一般的云厂商都提供了可视化的平台。服务监控&#xf…

如何实现torch.arange的tensor版本

文章目录 背景实现方案不可行的情况 背景 import torch我们都知道&#xff0c;torch.arange只支持数字&#xff0c;不支持tensor&#xff0c;如下&#xff1a; torch.arange(0,5,1)tensor([0, 1, 2, 3, 4]) 但是如果使用tensor&#xff0c;就会报错&#xff1a; torch.arang…

SpringBoot结合Redisson实现分布式锁

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Sp…

力扣 -- 474. 一和零(二维费用的背包问题)

解题步骤&#xff1a; 参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:int findMaxForm(vector<string>& strs, int m, int n) {//开一个三维的dp表vector<vector<vector<int>>> dp(strs.size()1,vector<vector<in…

DevEco Studio如何安装中文插件

首先 官网下载中文插件 由于DevEco是基于IntelliJ IDEA Community的&#xff0c;所有Compatibility选择“IntelliJ IDEA Community”&#xff0c;然后下载一个对应最新的就ok了。 最后打开Plugins页面&#xff0c;点击右上角齿轮 -> Install Plugin from Disk…。选择下载的…

AcWing算法提高课-5.6.1同余方程

宣传一下 算法提高课整理 CSDN个人主页&#xff1a;更好的阅读体验 原题链接 题目描述 求关于 x x x 的同余方程 a x ≡ 1 ( m o d b ) ax ≡ 1 \pmod b ax≡1(modb) 的最小正整数解。 输入格式 输入只有一行&#xff0c;包含两个正整数 a , b a,b a,b&#xff0c;用一…

python模拟表格任意输入位置

在表格里输入数值&#xff0c;要任意位置&#xff0c;我找到了好方法&#xff1a; input输入 1. 行 2. 列输入&#xff1a;1 excel每行输入文字input输入位置 3.2 表示输入位置在&#xff1a;3行个列是要实现一个类似于 Excel 表格的输入功能&#xff0c;并且希望能够指定输入…

怎么通过docker/portainer部署vue项目

这篇文章分享一下今天通过docker打包vue项目&#xff0c;并使用打包的镜像在portainer上部署运行&#xff0c;参考了vue-cli和docker的官方文档。 首先&#xff0c;阅读vue-cli关于docker部署的说明 vue-cli关于docker部署的说明https://cli.vuejs.org/guide/deployment.html#…

智慧工地源代码 SaaS模式云平台

伴随着技术的不断发展&#xff0c;信息化手段、移动技术、智能穿戴及工具在工程施工阶段的应用不断提升&#xff0c;智慧工地概念应运而生&#xff0c;庞大的建设规模催生着智慧工地的探索和研发。 什么是智慧工地&#xff1f; 伴随着技术的不断发展&#xff0c;信息化手段、移…

八、动态规划(Dynamic Programming)

文章目录 一、理论基础二、题目分类&#xff08;一&#xff09;基础题目2.[70.爬楼梯](https://leetcode.cn/problems/climbing-stairs/)&#xff08;1&#xff09;思路&#xff08;2&#xff09;代码&#xff08;3&#xff09;复杂度分析 3.[746. 使用最小花费爬楼梯](https:/…

正点原子嵌入式linux驱动开发——U-boot顶层Makefile详解

在学习uboot源码之前&#xff0c;要先看一下顶层Makefile&#xff0c;分析gcc版本代码的时候一定是先从顶层Makefile开始的&#xff0c;然后再是子Makefile&#xff0c;这样通过层层分析Makefile即可了解整个工程的组织结构。顶层Makefile也就是uboot根目录下的Makefile文件&am…

怪兽智能推出3D数字人虚拟主播,实时动作捕捉赋能直播营销,打造全新营销场景

怪兽智能科技推出了数字人直播新功能——3D数字人虚拟主播&#xff0c;通过实时动作捕捉技术&#xff0c;为直播营销场景注入了全新的活力和创意。这一功能将为企业带来更加生动、鲜活的营销体验&#xff0c;助力品牌在竞争激烈的市场中占据优势。 传统的直播营销方式往往依赖于…

论文笔记:Contrastive Trajectory Similarity Learning withDual-Feature Attention

ICDE 2023 1 intro 1.1 背景 轨迹相似性&#xff0c;可以分为两类 启发式度量 根据手工制定的规则&#xff0c;找到两条轨迹之间基于点的匹配学习式度量 通过计算轨迹嵌入之间的距离来预测相似性值上述两种度量的挑战&#xff1a; 无效性&#xff1a; 具有不同采样率或含有噪…

spring的面向切面编程

如果您觉得本博客的内容对您有所帮助或启发&#xff0c;请关注我的博客&#xff0c;以便第一时间获取最新技术文章和教程。同时&#xff0c;也欢迎您在评论区留言&#xff0c;分享想法和建议。谢谢支持&#xff01; 一、介绍什么是面向切面编程&#xff08;AOP&#xff09; 1.…

lv7 嵌入式开发-网络编程开发 05 字节序及IP地址转换

目录 1 主机字节序和网络字节序 1.1 什么是字节序&#xff1f; 1.2 查看主机字节序 2 字节序转换函数 3 IP地址字节序转换函数 4 练习 1 主机字节序和网络字节序 1.1 什么是字节序&#xff1f; 字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序&a…

Qt creator+cmake编译并安装

1、qt creator打开项目中的CMakeLists.txt 2、修改“构建设置“-“Cmake”-”Current Configuration“&#xff0c;其中&#xff0c;安装路径为CMAKE_INSTALL_PREFIX 3、修改“构建设置“-“构建的步骤”-”目标“&#xff0c;勾选"all"和"install" 4、构…

acwing198反素数(题解)

对于任何正整数 x&#xff0c;其约数的个数记作 g(x)&#xff0c;例如 g(1)1、g(6)4&#xfffd;(1)1、&#xfffd;(6)4。 如果某个正整数 x满足&#xff1a;对于任意的小于 x 的正整数 i&#xff0c;都有 g(x)>g(i)&#xff0c;则称 x为反素数。 例如&#xff0c;整数 1…