线程池概念介绍

news2024/9/21 19:51:52

一、初始化线程的四种方式

        1.继承Thread

        2.实现Runnable

        3.实现Callable接口+FutureTask

        4.线程池:两种主要初始化方式Executors.newFixedThreadPool()或new ThreadPoolExecutor()

方式1和方式2:主进程无法获取线程的运算结果。

方式3:主进程可以获取运算结果,但是不利于控制服务器中的线程资源,从而导致服务器资源耗尽。

方式4:线程池性能稳定,可以获取执行结果、捕获异常。但是在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的执行结果。

简单实用方式

继承Thread

public class ThreadTest {
    public static void main(String[] args) {
        System.out.printf("启动开始----");
        /**
         *  继承Thread
         */
        Thread thread = new Thread01();
        // 启动线程
        thread.start();
        System.out.printf("启动结束----")
    }

    static class Thread01 extends Thread {
        @Override
        public void run() {
            System.out.printf("当前线程:"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.printf("运行结果"+i);
        }
    }
    
}

运行结果:

实现Runnable

public class ThreadTest {
    public static void main(String[] args) {
        System.out.printf("启动开始----");
        /**
         *  实现Runnable
         */
        Runnable01 runnable01 = new Runnable01();
        new Thread(runnable01).start();
        System.out.printf("启动结束----");

    }

   
    static class Runnable01 implements Runnable{
        @Override
        public void run() {
            System.out.printf("当前线程:"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.printf("运行结果"+i);

        }
    }
   
}

运行结果:

实现Callable接口+FutureTask

如果使用:futureTask.get()获取结果,将会变成阻塞等待

public class ThreadTest {
    public static void main(String[] args) {
        System.out.printf("启动开始----");

        /**
         * 实现Callable接口+FutureTask
         */
        // FutureTask底层继承Runnable
        FutureTask futureTask = new FutureTask<>(new Callable01());
        new Thread(futureTask).start();
        // 可以会获取返回值,如果获取将会变成阻塞等待
        try {
            // 等待整个线程执行完成,获取返回结果(阻塞等待)
            Object o = futureTask.get();
            System.out.printf("o----"+o);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.printf("启动结束----");

    }

    static class Callable01 implements Callable<Integer> {


        @Override
        public Integer call() throws Exception {
            System.out.printf("当前线程:"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.printf("运行结果"+i);
            return i;
        }
    }
}

运行结果:

 线程池

public class ThreadTest {
// 创建线程池
    static ExecutorService service = Executors.newFixedThreadPool(10);
    public static void main(String[] args) {
        System.out.printf("启动开始----");
        /**
         * 线程池
         */
        // submit提交线程有返回参数,execute执行没有返回参数
        service.execute(new Runnable01());

    }
    static class Runnable01 implements Runnable{
        @Override
        public void run() {
            System.out.printf("当前线程:"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.printf("运行结果"+i);

        }
    }
}

二、线程池 

        为什么使用线程池,如果每个业务处理都使用原生的线程方法,会不断占用线程。在高并发环境下会将资源耗尽,无法做到总管理线程。所以我们将所有的多线程异步任务都交给线程池执行

        注意不应该执行每个业务都创建一个池,而是系统里最好控制线程池的数量

 线程池介绍

        1.Executors.newFixedThreadPool,创建一个固定大小的线程池。

        2.ThreadPoolExecutor,创建⼀个抢占式执⾏的线程池,是java中最常用的线程池

        3.Executors.newSingleThreadExecutor,创建⼀个可缓存的线程池。

        4.Executors.newScheduledThreadPool,创建单个线程数的线程池,可保证执行顺序。

        5.scheduleAtFixedRate,创建一个可执行延迟任务的线程池。

        6.Executors.newWorkStealingPool,创建一个⼀个单线程的可以执⾏延迟任务的线程池。

ThreadPoolExecutor为最原始的线程池,也是我们主要使用的线程池。

ThreadPoolExecutor线程池

 创建ThreadPoolExecutor比较复杂,最完整的有七个参数:

        1.corePoolSize:核心线程数,线程池创建好后就准备就绪的线程数量,不会因为空闲而回收,等待接受异步任务执行。(除非设置允许核心线程销毁参数

        2.maximumPoolSize:最大线程数量,线程池允许的最大线程数。控制资源并发。

        3.keepAliveTime:存活时间,当前线程数量大于核心数量,空闲线程等待最长时间,然后释放。

        4.TimeUnit:时间单位,存活时间的时间单位。

        5.BlockingQueue<Runnable>:阻塞队列,如果任务过多,就会将目前多的任务放到队列中。只要有空闲的线程,将会从队列中取出新的任务执行。

        6.ThreadFactory:线程创建工厂。

                --DefaultThreadFactory:默认工厂,创建普通线程。

                --PriorityThreadFactory:自定义工厂,创建具有优先级的线程,可指定线程优先级。

                --CustomizableThreadFactory:自定义工厂,创建自定义的线程,可自定义线程名、优先级、守护线程标志、线程组等属性。

                --NamedThreadFactory:自定义工厂,创建有名字的线程,会为每个线程设置一个名字。

                --SpringThreadFactory:Spring框架提供的线程工厂,用于创建可管理的线程。会创建一个新的线程,并将其注册到Spring的线程管理器中,以便管理线程的状态和执行情况。

        7.RejectedExecutionHandler,如果队列满了,按照指定的拒绝策略,拒绝执行任务。

                --AbortPolicy:默认策略,抛弃策略,当无法执行更多任务时抛弃任务并抛出异常。

                --CallerRunsPolicy:调用者运行策略,当线程池无法处理新任务时,将任务返回给提交任务的线程来同步执行。

                --DiscardPolicy:忽视策略,当线程池无法处理新任务时,直接抛弃,无任何提示。

                --DiscardOldestPolicy:抛弃旧策略,当线程池无法处理新任务时,抛弃队列中最早提交的任务,并尝试重新提交新任务。

运行流程

        1.线程池创建,准备好core数量的核心线程,准备接受任务。

        2.新的任务进来会用core准备好的空闲线程执行。

                (1)core满了,就将再进来的任务放到阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行。

                (2)阻塞队列满了,直接开新线程执行,最大能开到maximumPoolSize指定的数量。

                (3)maximumPoolSize满了就用RejectedExecutionHandler策略拒绝任务。 

                (4)maximumPoolSize都执行好了。最大线程数量空闲的线程会在keepAliveTime指定时间后销毁线程,最终保持到core大小。

为什么使用线程池

降低资源的消耗:

        通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗。

提高响应速度:

        因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行。

提高线程的可管理性:

        线程池回根据当前系统特点对池内的线程进行优化处理,减少创建和销毁带来的系统开销。无限的创建和销毁线程消耗系统资源、降低系统的稳定性。使用线程池进行统一分配。        

异步处理请移步:

Java线程池异步CompletableFuture,创建一步对象、回调方法、线程串行化、两任务组合、多任务组合-CSDN博客 

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

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

相关文章

MMO地图传送

本篇由以下四个点讲解&#xff1a; 创建传送点 传送点配置 编辑器扩展&#xff1a;传送点数据生成 传送协议与实现 创建传送点 建碰撞器触发 //位置归零 建一个传送门cube放到要传送的位置&#xff08;这个teleporter1是传出的区域 这是从另一张地图传入时的传送门 创建一…

mysql笔记—基础

1.SQL语句 DDL&#xff08;数据库对象操作&#xff09;、DML&#xff08;增删改&#xff09;、DQL&#xff08;查询&#xff09;、DCL&#xff08;用户和权限操作&#xff09; 2.DDL&#xff1a; 1.数据库操作&#xff1a; show databases; create database []; use []; sele…

网络工程师学习笔记——无线通信网

移动通信 从1G到3G都是针对语音通话设计的&#xff0c;只有4&#xff27;才可以与Internet衔接 1978年美国贝尔实验室开发了高级移动电话系统&#xff08;AMPS&#xff09;&#xff0c;可以随时随地的进行通信&#xff0c;采用蜂窝技术解决了公用通信系统所面临的大容量要求和…

初识Linux · 进度条

目录 前言&#xff1a; 1 缓冲区和回车换行 2 进度条 前言&#xff1a; 我们目前学习了些许知识&#xff0c;已经足够支持我们写一个非常非常小的项目了&#xff0c;即进度条&#xff0c;相信大家都有过下载游戏&#xff0c;等待游戏更新完成的时候&#xff0c;那么此时就有…

电器维修系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;客服聊天管理&#xff0c;基础数据管理&#xff0c;公告管理&#xff0c;新闻信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;新闻信息&#xff0c;我的 开发系…

站长工具 API 接口,助力网站管理新高度

站长工具是一款非常实用的网站管理工具&#xff0c;通过其提供的API接口&#xff0c;可以轻松实现多种功能&#xff0c;如域名反查、域名备案查询、IPV6归属地查询等。这些功能可以帮助网站管理员更好地管理和优化自己的网站。以下是简单的代码示例&#xff0c;展示了如何使用站…

康姿百德公司官网柔压磁性枕豪华款高科技邂逅温柔夜活力满满!

康姿百德豪华柔压磁性枕慢回弹拥抱每寸肌肤&#xff0c;科技面料让呼吸自由夜夜好眠不是梦&#xff01; 现代家居设计不仅注重美观&#xff0c;更强调功能性和舒适性。康姿百德柔压磁性枕&#xff08;豪华款&#xff09;通过将高科技材料与创新设计结合&#xff0c;为我们的家…

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1&#xff09;getTransletInstance2&#xff09;defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码&…

最大N个数与最小N个数的和

题目描述 给定一个数组&#xff0c;编写一个函数来计算它的最大N个数与最小N个数的和。你需要对数组进行去重 说明: 数组中数字范围[0&#xff0c;1000]最大N个数与最小N个数不能有重叠&#xff0c;如有重&#xff0c;输入非法返回-1输入非法返回-1 输入描述 第一行输入M&a…

uboot:配置编译

了解BSP 在嵌入式系统中&#xff0c;BSP&#xff08;Board Support Package&#xff09;被称为板级支持包或板级支持软件。它是一组针对特定硬件平台的软件支持包&#xff0c;为开发人员提供了一个统一的接口层&#xff0c;简化了硬件和软件之间的交互。BSP的主要功能和特点如…

Python数据分析-绘制图表

示例1&#xff1a; from pyecharts.charts import Bar # 柱状图 from pyecharts import options as optsfrom pyecharts.render import make_snapshotbar Bar() bar.add_xaxis([一月, 二月, 三月, 四月, 五月]) bar.add_yaxis("销售额", [10, 20, 15, 25, 30])# 配…

spring 事物使用场景说明

事务使用场景。 在某些业务场景下&#xff0c;如果一个请求中&#xff0c;需要同时写入多张表的数据。为了保证操作的原子性&#xff08;要么同时成功&#xff0c;要么同时失败&#xff09;&#xff0c;避免数据不一致的情况&#xff0c;我们一般都会用到spring事务。 确实&am…

使用Node-API进行异步任务开发

一、Node-API异步任务机制概述 Node-API异步任务开发主要用于执行耗时操作的场景中使用&#xff0c;以避免阻塞主线程&#xff0c;确保应用程序的性能和响应效率。 1、应用场景&#xff1a; 文件操作&#xff1a;读取大型文件或执行复杂的文件操作时&#xff0c;可以使用异步工…

TCP远程命令执行

目录 一. 命令集 二. 命令执行模块实现 三. 服务端模块实现 四. 服务端调用模块实现 五. 客户端模块实现 六. 效果展示 此篇教大家如何利用TCP进行远程命令执行。 一. 命令集 将值得信任的命令放进一个txt文件中&#xff0c;执行命令时&#xff0c;就去这…

英语每日一段 195

Promising economic indicators won’t instantly reverse the lingering impact of hard times for millions of families, workplace culture expert Jessica Kriegel said. “Perception and reality are sometimes aligned and sometimes not,” Kriegel told Newsweek. “…

这才是程序猿梦想的终端,赶快动手搞起来

文章目录 目标资源列表安装iTerm2安装oh-my-zsh安装颜色主题查找配置文件将配置内容复制到本地设置iTerm2 安装NERD FONTS下载字体安装设置iTerm2 安装PowerLevel10k修改.zshrc重新加载配置 安装插件下载[语法高亮](#syntaxhighlighting)下载[命令提示](#autosuggestions)配置插…

git的使用和gdb工具

1.git的使用 首先现在gitee上新建一个仓库 然后复制克隆链接到本地仓库 在本地仓库中&#xff0c;我们可以用git status查看仓库状态 我们要提交代码就是要三步 git add 文件名 git commit -m "写提交的日志" git push 将代码上传到远端仓库 然后你就完成一次提…

AIOT人工智能物联网六大场景

AIOT&#xff08;人工智能物联网&#xff09;融合了人工智能技术和物联网技术&#xff0c;实现了设备之间的智能互联和数据交互&#xff0c;在多个场景中都有广泛的应用。以下是一些主要的AIOT场景&#xff1a; 一、智能交通 智能汽车&#xff1a; 自动驾驶是AIOT在智能交通领…

tolower/toupper 函数讲解

目录 1.函数介绍 2.示例如下&#xff1a; 方源一把抓住VS2022&#xff0c;又是顷刻炼化&#xff01;&#xff1f; 1.函数介绍 C语言中提供了两种函数用于字符大小的转换 tolower可以将大写字符转小写字符&#xff0c;toupper可以将小写字符转大写字符 tolower函数与touppe…

设计并用Java实现一个简易的规则引擎

文章目录 前言正文一、代码结构二、核心代码2.1 上下文数据接口 ContextData.java2.2 规则接口 Rule.java2.3 规则引擎接口 RuleEngine.java2.4 规则引擎上下文类 RuleEngineContext.java2.5 规则引擎默认实现类 DefaultRuleEngine.java2.6 执行时出错监听器接口 ExecuteOnErro…