首页 > 编程语言 >Java线程池和执行流程

Java线程池和执行流程

时间:2024-08-12 11:22:51浏览次数:15  
标签:Java 队列 流程 任务 线程 提交 executor 执行

在 Java 中,常见的四种线程池包括:

1. newFixedThreadPool(固定大小线程池)

  • 应用场景:适用于需要限制线程数量,并且任务执行时间比较均匀的场景,例如服务器端的连接处理。
  • 优点:线程数量固定,能够有效地控制并发线程数,避免过多的线程竞争资源。
  • 缺点:如果线程在执行任务过程中出现异常导致线程终止,而新任务被提交到线程池时,可能会出现等待,直到有线程被释放。
ExecutorService executor = Executors.newFixedThreadPool(5);

示例(下面的newCachedThreadPool、newSingleThreadExecutor的使用是类似的):

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个固定大小为 5 的线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // 提交 10 个任务到线程池
        for (int i = 1; i <= 10; i++) {
            executor.execute(new Task(i));
        }

        // 关闭线程池,不再接受新任务,但会等待已提交任务完成
        executor.shutdown();
    }

    static class Task implements Runnable {
        private int taskNumber;

        public Task(int taskNumber) {
            this.taskNumber = taskNumber;
        }

        @Override
        public void run() {
            System.out.println("Task " + taskNumber + " is running on thread: " + Thread.currentThread().getName());
            try {
                // 模拟任务执行耗时
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task " + taskNumber + " is completed");
        }
    }
}

2. newCachedThreadPool(可缓存线程池)

  • 应用场景:适用于执行很多短期异步任务的场景,例如网页服务器中的请求处理。
  • 优点:可以根据需要创建新线程,如果有可用的线程则复用,能灵活应对短时间内大量的任务请求。
  • 缺点:因为线程数量不固定,可能会创建大量线程,从而导致系统资源消耗过多。
ExecutorService executor = Executors.newCachedThreadPool();

3. newSingleThreadExecutor(单线程池)

  • 应用场景:适用于需要按顺序依次执行任务的场景,例如日志记录。
  • 优点:保证任务按顺序执行,避免多线程环境下的并发问题。
  • 缺点:执行效率相对较低,不适合并发量大的任务。
ExecutorService executor = Executors.newSingleThreadExecutor();

4. newScheduledThreadPool(定时任务线程池)

  • 应用场景:适用于需要执行定时任务或者周期性任务的场景,例如定时数据备份。
  • 优点:能够准确地按照设定的时间间隔执行任务。
  • 缺点:相对复杂,配置不当可能导致任务执行不准确。
ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);

示例:

package com.yuanmomo.demo.thread;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个大小为 5 的定时任务线程池
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);

        // 延迟 3 秒后执行一次任务
        executor.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("延迟任务在3秒后执行");
            }
        }, 3, TimeUnit.SECONDS);

        // 每隔 2 秒执行一次任务
        executor.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行周期任务");
            }
        }, 0, 2, TimeUnit.SECONDS);

        // 运行一段时间后关闭线程池
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executor.shutdown();
    }
}

线程池执行流程

在这里插入图片描述

  1. 任务提交
    • 当向线程池提交一个任务时,线程池会首先判断当前运行的线程数量是否小于核心线程数量。
    • 如果小于,会创建一个新的线程来执行任务。
  2. 核心线程池已满
    • 若核心线程数量已达到设定的最大值,新提交的任务会被放入任务队列中等待执行。
  3. 任务队列已满
    • 如果任务队列已满,并且当前运行的线程数量小于最大线程数,线程池会创建新的线程来执行任务。
  4. 达到最大线程数
    • 当线程数量达到最大线程数,并且任务队列已满时,新提交的任务会根据拒绝策略进行处理。
  5. 线程回收
    • 当线程空闲时间超过一定限度(可设置),且当前运行线程数大于核心线程数时,多余的空闲线程会被回收。

例如:
假设线程池的核心线程数为 5,最大线程数为 10,任务队列容量为 100,拒绝策略为抛出异常。

开始时,陆续提交 5 个任务,线程池会创建 5 个核心线程来执行这些任务。

接着继续提交任务,只要任务数未超过 100,新任务会被放入任务队列等待执行。

当任务队列已满,继续提交任务,此时会创建新的线程(最多到 10 个)来执行任务。

若线程数达到 10 且任务队列已满,再提交新任务,就会根据拒绝策略抛出异常。

线程来执行这些任务。

接着继续提交任务,只要任务数未超过 100,新任务会被放入任务队列等待执行。

当任务队列已满,继续提交任务,此时会创建新的线程(最多到 10 个)来执行任务。

若线程数达到 10 且任务队列已满,再提交新任务,就会根据拒绝策略抛出异常。

标签:Java,队列,流程,任务,线程,提交,executor,执行
From: https://blog.csdn.net/yuanmomoya/article/details/141126839

相关文章

  • java中去重复的id
    1.Stringprojectids="";2.if(StringHelper.isNotEmpty(gatheringinfo.getCol1())&&gatheringinfo.getCol1().length()>0){projectids+=gatheringinfo.getCol1()+",";}3.if(StringHelper.isNotEmpty(projectids)){projectids=......
  • Java自动化测试框架-08 - TestNG之并行性和超时篇 (详细教程)
    一、并行性和超时您可以指示TestNG以各种方式在单独的线程中运行测试。可以通过在suite标签中使用parallel属性来让测试方法运行在不同的线程中。这个属性可以带有如下这样的值:二、并行套件(suites)如果您正在运行多个套件文件(例如“ javaorg.testng.TestNGtestng1.xml......
  • Epson C4校准和Python通讯流程
    第一章简介1.1机器人型号EsonC41.2.目的使用EponC4机械臂,通过python进行指令控制,在通讯之前,进行了原点和工具坐标系的校准1.3.流程C4机械臂的机械原点校准C4机械臂的工具坐标系校准C4机械臂的通讯第二章机械原点校准2.1.原点校准-硬件操作2.1.1.原点校准......
  • 基于 JavaFx 搭建的实用小工具集合
    大家好,我是Java陈序员。作为一名后端程序员,常常需要在电脑上安装各种工具软件来支持日常开发。那么,是否有一款工具集合,包含各种工具,可以省去一一安装呢?答案是有的!今天,给大家介绍一个基于JavaFx实现的工具集合,包含了各式各样的开发工具,以及一些有趣的小工具。关注微信公众......
  • Java学习笔记1--JDK,JRE和JVM
    1、Java开发环境Java开发环境是指Java程序员开发、编写、测试和调试Java程序所使用的所有工具和技术。Java开发环境通常由以下几个部分组成:JDK(JavaDevelopmentKit):JDK是Java开发环境的核心组件,它包括了Java编译器、JRE(Java运行环境)、JavaDoc文档生成器和其他一些工具。JDK是J......
  • Java学习笔记2--JDK的安装和配置
    一.进入oracle官网,下载jdkoracle官网:Oracle|CloudApplicationsandCloudPlatformps:不同的浏览器,可能进入oracle官网,会只显示部分内容,所以建议使用googleChrome浏览器在下载之前,首先需要去查看本机电脑的配置型号,如下图,右键---此电脑---选择点击属性,显示x64版本如下......
  • 大模型备案流程最详细说明【评估测试题+附件】
    2024年3月1日,我国通过了《生成式人工智能服务安全基本要求》(以下简称《AIGC安全要求》),这是目前我国第一部有关AIGC服务安全性方面的技术性指导文件,对语料安全、模型安全、安全措施、词库/题库要求、安全评估等方面提出了具体规范和要求。(一)适用主体《AIGC安全要求》的适用主......
  • Java动态代理与方法拦截实战解析
    Java动态代理与方法拦截实战解析在Java编程中,动态代理是一种强大的技术,它允许我们在运行时创建接口的代理实例,并且可以拦截方法调用。本文将通过一个具体的实例,详细解析如何使用JDK的动态代理机制来实现方法拦截,以及如何编写通用的方法拦截器。实现InvocationHandler首先......
  • 深入解析@JsonValue注解在Java序列化中的应用
    深入解析@JsonValue注解在Java序列化中的应用在Java开发中,对象序列化是一个常见的需求,尤其是在进行网络通信或者数据持久化时。Jackson库作为Java领域内一个非常流行的JSON处理库,提供了强大的序列化和反序列化功能。在Jackson2.9版本之后,@JsonValue注解的引入,为开发者提供......
  • 【Java数据结构】---泛型
    乐观学习,乐观生活,才能不断前进啊!!!我的主页:optimistic_chen我的专栏:c语言,Java欢迎大家访问~创作不易,大佬们点赞鼓励下吧~文章目录包装类装箱和拆箱泛型泛型语法擦除机制泛型的上届泛型方法静态泛型方法完结包装类在Java中,由于基本类型不是继承自Objec......