[进阶]Java:线程池、处理Runnable、Callable任务、使用Executors得到线程池

news2024/10/7 12:21:23

什么是线程池?

  • 线程池就是一个可以复用线程的技术。

不实用线程池的问题?

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

谁代表线程池?

  • JDK 5.0起提供了代表线程池的接口:ExecutorService。

如何得到线程池对象?

  • 方式一:使用ExecutorService的实现类ThreadPoolExecutor自创建一个线程池对象。
  • 方式二:使用Executors(线程池的工具类)调用方法返回不同特点的线程池对象。

ThreadPoolExcutor构造器

  • 参数一:corePoolSize :指定线程池的核心线程的数量。
  • 参数二:maximumPoolsize:指定线程池的最大线程数量。
  • 参数三:keepAliveTime:指定临时线程的存活时间。
  • 参数四:unit:指定临时线程存活的时问单位(秒、分、时、天)
  • 参数五:workQueue:指定线程池的任务队列。
  • 参数六:threadFactory:指定线程池的线程工厂。
  • 参数七:handler:指定线程池的任务拒绝策略(线程都在忙,任务队列也满了的时候,新任务来了该怎么处理)

创建代码演示如下:

public class ThreadPoolTest1 {
    public static void main(String[] args) {
        ExecutorService pool = new ThreadPoolExecutor(3,5,8,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
    }
}

线程池的注意事项

1.临时线程什么时候创建?

  • 新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程。

2.什么时候开始拒绝新任务?

  • 核心线程和临时线程都在忙,任务队列也满了,新的任务过来的时候才会开始拒绝任务。

线程池处理Runnable任务

ExecutorService的常用方法

 新任务拒绝策略

 代码演示如下:

public class MyRunnable implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "===> 输出666~");
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

public class ThreadPoolTest1 {
    public static void main(String[] args) {
        // 通过ThreadPoolExecutor创建一个线程池对象
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        Runnable target = new MyRunnable();
        pool.execute(target);// 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
        pool.execute(target);// 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
        pool.execute(target);// 线程池会自动创建一个新线程,自动处理这个任务,自动执行的!
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        // 到了临时线程的创建时机了
        pool.execute(target);
        pool.execute(target);
        // 到了新任务拒绝时机了
        pool.execute(target);

        //pool.shutdown(); // 等着线程池的任务全部执行完毕后,再关闭线程池
        //pool.shutdownNow(); // 立即关闭线程池!不管任务是否执行完毕!
    }
}

线程池处理Callable接口

代码演示如下:
 

public class MyCallable implements Callable<String> {
    private int n;
    public MyCallable(int n){
        this.n = n;
    }
    @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;
    }
}
public class ThreadPoolTest2 {
    public static void main(String[] args) throws Exception{
        // 1.通过ThreadPoolExecutor创建一个线程池对象
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());
        // 2.使用线程处理Callable任务。
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());

        pool.shutdown();
    }
}

使用Executors得到线程池

  • Executors是一个线程池的工具类,提供了很多静态方法用于返回不同特点的线程池对象。

 

注意:这些方法的底层,都是通过线程池的实现类ThreadPoolExecutor创建的线程池对象。

代码演示如下:

public class ThreadPoolTest3 {
    public static void main(String[] args) throws Exception{
        // 1.通过ThreadPoolExecutor创建一个线程池对象
//        ExecutorService pool = new ThreadPoolExecutor(3, 5, 8,
//                TimeUnit.SECONDS, new ArrayBlockingQueue<>(4), Executors.defaultThreadFactory(),
//                new ThreadPoolExecutor.AbortPolicy());
        //1-2.通过Executors创建一个线程池对象
        ExecutorService pool = Executors.newFixedThreadPool(13);
        //核心线程池数量到底配置多少?
        //计算密集型的任务:核心线程数量 = CPU的核数 + 1
        //IO密集型的任务:核心线程数量 = CPU核数 * 2


        // 2.使用线程处理Callable任务。
        Future<String> f1 = pool.submit(new MyCallable(100));
        Future<String> f2 = pool.submit(new MyCallable(200));
        Future<String> f3 = pool.submit(new MyCallable(300));
        Future<String> f4 = pool.submit(new MyCallable(400));

        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());

        pool.shutdown();
    }
}

Executors使用可能存在的陷阱

  • 大型并发系统环境中使用Executoes如果不注意可能会出现系统风险。

 

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

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

相关文章

MIT 6.S081 (BOOK-RISCV-REV1)教材第四章内容 --中

MIT 6.S081 教材第四章内容 -- 中 引言Debug Trap代码执行流程进入Trap前发生Trap时uservec函数Issue usertrap函数usertrapret函数userret函数 小结 引言 MIT 6.S081 2020 操作系统 本文为MIT 6.S081课程第四章教材内容翻译加整理。 本课程前置知识主要涉及: C语言(建议阅读…

二进制部署k8集群(上)搭建单机matser和etcd集群

1. 单机matser预部署设计 组件部署&#xff1a; 2.操作系统初始化配置 注意&#xff1a;该操作在所有node节点上进行&#xff0c;为k8s集群提供适合的初始化部署环境 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld iptables -F && iptables -t n…

985大学学生故意挂科为延毕?赖校族的无奈。

“他室友挂了4科&#xff0c;答辩随便写了几句&#xff0c;一问三不知。” “然后呢&#xff1f;他室友延毕了吗&#xff1f;” “没有。导员找他谈话&#xff0c;说让他室友按时毕业&#xff0c;因为想延毕的人太多了&#xff0c;别人挂的都比他室友多。” 以上对话不仅仅是…

PLC原理及PLC+FPGA(SOC)架构方案简介

一、PLC原理简介 工业生产和科技的发展都离不开PLC的自动化控制&#xff0c;PLC可以广义的理解为&#xff1a; 集中的继电器延伸控制柜&#xff0c;实际的生产应用中&#xff0c;PLC大大的节省了工业控制的成本&#xff0c;加强了设备的集中管理和自动控制。 PLC&#xff08…

【人脸检测——基于机器学习4】HOG特征

前言 HOG特征的全称是Histograms of Oriented Gradients,基于HOG特征的人脸识别算法主要包括HOG特征提取和目标检测,该算法的流程图如下图所示。本文主要讲HOG特征提取。 HOG特征的组成 Cell:将一幅图片划分为若干个cell(如上图绿色框所示),每个cell为8*8像素 Block:选…

NET Core 6.0 webapi 简单使用+连接数据库

文章目录 环境创建WebApi并防止Api冲突Swagger添加注释连接sqlite数据库Nuget包代码 环境 ASP.NET coreNET core 6.0 创建WebApi并防止Api冲突 using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc;namespace WebApi1.Controllers {//[Route("api/[control…

三、Docker基本使用及命令

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、帮助启动类命令1.1 启动docker1.2 停止docker1.3 重启docker1.4 查看docker状态1.5 开机启动1.6 查看docker概要信息1.7 查看docker总体帮助文档1.8 查看docker命令…

Qt QPainter

QPainter需要在QPaintEvent中绘画 绘画需要笔 绘画需要的基础头文件 QPainter QPaintEvent QPen QPainter 建立painter之后就可以绘画&#xff0c;pen这些都有默认实现 可画设备 圆用椭圆画 重新绘画 重新绘画只需要重新加入画笔就可以 painter.setPen(pen); // 重新…

Shell脚本中的数值计算:使用数学运算实现数值操作

前言 沐风晓月带你学云原生开发&#xff0c;从零开始&#xff0c;我们出发&#xff0c;让知识学习不再难。 &#x1f3e0;个人主页&#xff1a;我是沐风晓月 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是沐风晓月&#xff0c;阿里云社区博客专家 &#x1f609;&…

高数基础6

目录 导数与微分 导数的定义式&#xff1a; 导数的第二个定义式&#xff1a; 左右导数 区间内可导 例题&#xff1a; 例题2&#xff1a; 微分 微分的概念 例题&#xff1a; 导数的几何意义&#xff1a; 切线方程与法线方程 例题&#xff1a; 连续可导可微之间的关系…

短视频矩阵系统源码开发部署分享

短视频矩阵系统源码开发需要用到以下技术&#xff1a; 1.前端技术&#xff1a;HTML、CSS、JavaScript、Vue.js等前端框架。 2.后端技术&#xff1a;Java、Python、PHP等后端语言及相关框架&#xff0c;如Spring Boot、Django、Laravel等。 3.移动开发技术&#xff1a;Androi…

文本匹配模型实验报告-text2vec

文本匹配模型实验报告-text2vec 尽管基于BERT的模型在NLP诸多下游任务中取得了成功&#xff0c;直接从BERT导出的句向量表示往往被约束在一个很小的区域内&#xff0c;表现出很高的相似度&#xff0c;因而难以直接用于文本语义匹配。为解决BERT原生句子表示这种“坍缩”现象&a…

软件开发流程的演变:敏捷开发(XP、SCRUM)、DevOps(CI/CD)的概念

一、软件开发流程的演变 二、传统瀑布模型 1.瀑布模型特点 软件开发的各项活动严格按照线性方式进行 当前活动接受上一项活动的工作结果 当前活动的工作结果需要进行验证 2.瀑布模型优缺点 优点 开发的各个阶段比较清晰 强调早期计划及需求调查 适合需求稳定的产品开发 缺点…

权限获得第一步

根据题目提示flag就是某个密码&#xff0c;并且flag不是常规形式 打开文件后看起来是一个linux的用户密码段 反正最后两个最可疑了&#xff0c;linux中密码的存储形式是MD5加密 第一个数据解码失败 第二个密文解密成功 果然不是常规形式&#xff0c;常规的flag一本都是是英文加…

在Linux系统下使用Ventoy制作Windows安装U盘

文章目录 介绍Ventoy 简介PE 简介 制作 Ventoy U 盘安装 Ventoy将 Ventoy 安装到 U 盘 制作 PE 辅助系统下载优启通下载操作系统 ISO 镜像 安装操作系统准备工作安装系统 介绍 Ventoy 简介 Ventoy 是一个制作可启动 U 盘的开源工具。有了 Ventoy &#xff0c;就无需反复地格式…

IDE/记录VS2015WinSDK安装过程中增删的系统组件和环境变量

文章目录 概述看看"干净OS环境"安装VS软件后系统目录变化环境变量变化新增的组件程序 Qt及其VS插件安装后安装WinSDK后安装Win10SDK前安装WinSDK后 卸载VS2015其他软件的影响 概述 本文旨在&#xff0c;通过记录干净OS环境下 VS2015、Qt、WinSDK 软件安装前后&#…

使用mount临时挂载出现mount error(13): Permission denied

问题报错 mount error(13): Permission denied Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) //报错信息&#xff0c;提示账号密码错误&#xff0c;其实并不是 添加secntlmssp参数即可&#xff1b;中途可能需要等一些时间 mount -t cifs -o usernamelisi,p…

在低配Windows上部署原版llama.cpp

现在大语言模型的部署&#xff0c;通常都需要大的GPU才能实现&#xff0c;如果是仅仅想研究一下&#xff0c;大语言模型的算法&#xff0c;我们是很想能够直接在我们的工作电脑上就能直接运行的&#xff0c;llama.cpp就是很好的实现。 LLaMa.cpp使用int4这种数值格式&#xff…

【js步骤引导】基于jquery实现步骤引导进度条效果(附源码)

【写在前面】 步骤引导条这个功能其实在我们很多业务系统中是最常见的&#xff0c;尤其是快递订单、审批流程、上传资源等涉及步骤操作的业务中广泛应用&#xff0c;因此今天我也详细的和大家讲讲如何基于jquery去实现步骤引导效果&#xff0c;支持上一步下一步的切换。 【涉…

【云计算】HBase表操作

文章目录 前言一、shell创建二、操作 前言 HBase是一个分布式、可扩展的、非关系型的NoSQL数据库。它是建立在Hadoop HDFS上的一个开源的数据库管理系统。HBase的设计目标是提供高可靠性、高可扩展性、高性能、高延迟、高容错性和高可用性。 HBase是一种面向列的数据库&#…