Java 线程池的管理

引言

线程池是并发编程中常用的资源管理模式,能够有效地管理和复用线程资源,提高系统性能和资源利用率。Java 提供了一整套线程池框架,使得创建和管理线程池变得非常方便。本文将详细介绍如何使用 Java 线程池框架中的关键方法来提交任务、关闭线程池以及获取线程池状态。

提交任务:submit()execute()

在 Java 线程池中,任务可以通过 submit()execute() 方法提交到线程池中进行执行。

execute()

execute() 方法用于提交不需要返回结果的任务,任务必须实现 Runnable 接口:

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

public class ExecuteExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task is running by " + Thread.currentThread().getName());
        };

        executorService.execute(task);
        executorService.shutdown();
    }
}

在上述代码中,execute() 方法将任务提交给线程池执行,但不会返回任何结果。

submit()

submit() 方法用于提交需要返回结果的任务,可以提交实现 CallableRunnable 接口的任务,并返回一个 Future 对象:

import java.util.concurrent.*;

public class SubmitExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Callable<String> task = () -> {
            TimeUnit.SECONDS.sleep(1);
            return "Task completed by " + Thread.currentThread().getName();
        };

        Future<String> future = executorService.submit(task);

        try {
            String result = future.get();
            System.out.println(result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }
}

在上述代码中,submit() 方法将任务提交给线程池执行,并返回一个 Future 对象,可以通过 Future 对象获取任务的执行结果。

关闭线程池:shutdown()shutdownNow()

在使用完线程池后,需要关闭线程池以释放资源。Java 提供了两种方法来关闭线程池:shutdown()shutdownNow()

shutdown()

shutdown() 方法启动有序关闭,在调用此方法后线程池不再接收新任务,但会继续执行已提交的任务:

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

public class ShutdownExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task is running by " + Thread.currentThread().getName());
        };

        for (int i = 0; i < 5; i++) {
            executorService.execute(task);
        }

        executorService.shutdown();

        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

在上述代码中,shutdown() 方法启动有序关闭,awaitTermination() 方法等待线程池终止,若在指定时间内未终止则调用 shutdownNow() 进行强制关闭。

shutdownNow()

shutdownNow() 方法试图停止所有正在执行的任务并返回等待执行的任务列表:

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

public class ShutdownNowExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task is running by " + Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(10); // 模拟长时间运行的任务
            } catch (InterruptedException e) {
                System.out.println("Task was interrupted");
            }
        };

        for (int i = 0; i < 5; i++) {
            executorService.execute(task);
        }

        executorService.shutdownNow();
    }
}

在上述代码中,shutdownNow() 方法试图停止所有正在执行的任务,且返回尚未开始执行的任务列表。

获取线程池状态:isShutdown()isTerminated()

在关闭线程池后,可以使用 isShutdown()isTerminated() 方法获取线程池的状态。

isShutdown()

isShutdown() 方法用于判断线程池是否已被关闭,但未必所有任务都已完成执行:

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

public class IsShutdownExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task is running by " + Thread.currentThread().getName());
        };

        for (int i = 0; i < 5; i++) {
            executorService.execute(task);
        }

        executorService.shutdown();
        System.out.println("Is shutdown: " + executorService.isShutdown());
    }
}

在上述代码中,isShutdown() 方法用于判断线程池是否已被关闭。

isTerminated()

isTerminated() 方法用于判断线程池中的所有任务是否都已完成执行:

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

public class IsTerminatedExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        Runnable task = () -> {
            System.out.println("Task is running by " + Thread.currentThread().getName());
        };

        for (int i = 0; i < 5; i++) {
            executorService.execute(task);
        }

        executorService.shutdown();

        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }

        System.out.println("Is terminated: " + executorService.isTerminated());
    }
}

在上述代码中,isTerminated() 方法用于判断线程池中的所有任务是否都已完成执行。

结论

Java 线程池提供了一整套方便的 API 来管理和控制任务的执行,包括任务的提交、线程池的关闭以及获取线程池的状态。通过合理使用这些方法,可以有效地提高系统的性能和资源利用率,同时确保线程池资源的正确释放和任务的顺序执行。理解并正确使用 Java 线程池管理方法,是编写高效且稳定的并发程序的关键。

希望本文能帮助你理解 Java 线程池的管理方法及其使用场景。如果你有任何问题或建议,欢迎留言讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WordPress网站违法关键词字过滤插件下载text-filter

插件下载地址&#xff1a;https://www.wpadmin.cn/2025.html 插件介绍 WordPress网站违法关键词字过滤插件text-filter由本站原创开发,支持中英文关键字自动替换成**号&#xff0c;可以通过自定义保存修改按钮增加“预设关键字”&#xff0c;也可以导入定义好的txt文本形式的关…

single_test_funi.py: error: the following arguments are required: img

parser.add_argument(img, defaultS/1.jpg, helpImage file) 当你已经指定了文件路径&#xff0c;还是报错怎么办&#xff1f; parser.add_argument(img, nargs?, defaultS/1.jpg, helpImage file) nargs? 表示 config 参数是可选的。如果用户没有提供这个参数&#xff0c…

【ARMv8/v9 GIC 系列 5.6 -- GIC 超优先级中断详细介绍】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 Interrupt superpriority超优先级中断的特性和应用Physical interface interrupt signalsPhysical Group 1 Non-NMI for Current Security StatePhysical Group 1 for Other Security State, or a Group 0 Non-NMIPhysical Group 1 …

JVM原理(十八):JVM虚拟机的编译器优化技术

1. 编译器优化技术 编译器的目标虽然是做程序代码翻译为本地机器 码的工作&#xff0c;但其实难点并不在于能不能成功翻译出机器码&#xff0c;输出代码优化质量的高低才是决定编译器优秀与否的关键。 1.1. 优化技术概览 即时编译器对这些代码优化变换是建立在代码的中间表示…

基于Android Studio点餐项目,点餐app

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 实现登录、注册、注销功能&#xff0c;退出登录等功能&#xff0c; 以及基本的选择店铺点餐&#xff0c;加入购物车和结算等功能&#xff0c;以及可以增加或者减少商品的个数&#xff0c; 同时可以同步价格的总量。以…

两年经验前端带你重学前端框架必会的ajax+node.js+webpack+git等技术的个人学习心得、作业及bug记录 Day1

黑马程序员前端AJAX入门到实战全套教程&#xff0c;包含学前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;&#xff0c;一套全覆盖 Day1 你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ ​…

沙龙回顾|MongoDB如何充当企业开发加速器?

数据不仅是企业发展转型的驱动力&#xff0c;也是开发者最棘手的问题。前日&#xff0c;MongoDB携手阿里云、NineData在杭州成功举办了“数据驱动&#xff0c;敏捷前行——MongoDB企业开发加速器”技术沙龙。此次活动吸引了来自各行各业的专业人员&#xff0c;共同探讨MongoDB的…

大话C语言:第27篇 内存模型

1 存储硬件概述 现代计算机遵循冯诺依曼体系结果&#xff0c;存储分为&#xff1a; 外部存储器&#xff1a;长期存放数据&#xff0c;掉电不丢失数据。例如&#xff0c;硬盘、flash、rom、u 盘、光盘、磁带。 内部存储器&#xff1a;暂时存放数据&#xff0c;掉电数据丢失。例…

小白学python(第六天)循环之异变

本篇文章给大家讲解的是循环语句&#xff0c;那么闲话少叙&#xff0c;我们进入正题 在c、Java中循环都是三剑客&#xff0c;那么大家可还记得是哪三位剑客吗 剑客一&#xff1a;while循环 剑客二&#xff1a;for循环 剑客三&#xff1a;do{……}while&#xff08;&…

springcloud-alibba之FeignClient

代码地址&#xff1a;springcloud系列: springcloud 组件分析拆解 1.FeignClient的集成 springboot版本&#xff1a;3.1.5 springcloud组件版本&#xff1a;2022.0.4 nacos客户端的版本&#xff1a;2.3.2 1.引pom 这里引入了nacos和feginclient的版本 <dependency>…

MongoDB 单节点升级为副本集高可用集群(1主1从1仲裁)

作者介绍&#xff1a;老苏&#xff0c;10余年DBA工作运维经验&#xff0c;擅长Oracle、MySQL、PG、Mongodb数据库运维&#xff08;如安装迁移&#xff0c;性能优化、故障应急处理等&#xff09; 公众号&#xff1a;老苏畅谈运维 欢迎关注本人公众号&#xff0c;更多精彩与您分享…

SpringBoot 实现视频分段播放(通过进度条来加载视频)

需求&#xff1a;现在我本地电脑中有一个文件夹&#xff0c;文件夹中都是视频&#xff0c;需要实现视频播放的功能。 问题&#xff1a;如果通过类似 SpringBoot static 文件夹的方式来实现&#xff0c;客户端要下载好完整的视频之后才可以播放&#xff0c;并且服务端也会占用大…

计算机网络之以太网

上文内容&#xff1a;总线局域网以及冲突的解决方法 1.以太网的起源 1.1起源 60年代末期&#xff0c;夏威夷大学Norman Abramson等研制ALOHA无线网络系统,实现Oahu岛上的主机和其它岛及船上的读卡机和终端通信&#xff1b; 出境信道地址&#xff1a;主机到终端&#xff1…

vue3 + 百度地图 实现多坐标生成轨迹的两种种方式

本次依然是关于百度地图中常见的一个问题&#xff0c;此次共使用了两种方式并做了一些分析及处理&#xff0c;希望有所帮助。如有问题可以评论或私信。 一、便捷方式 优点&#xff1a;便捷&#xff0c;所用的api方法是根据坐标进行计算后绘制路线&#xff0c;所以路线相对准确…

制定事件响应计划的四个关键步骤,如何做到风险闭环

一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f;一个有效的安全事件响应策略包括四个关键组成部分&#xff0c;它们协同工作以确保对网络安全问题的快速和有效响应。 一个有效的安全事件响应策略的关键组成部分有哪些&#xff1f; 一个有效的安全事件响应策略包括…

Java常用算法集合扩容机制分析

基础篇 基础篇要点&#xff1a;算法、数据结构、基础设计模式 1. 二分查找 要求 能够用自己语言描述二分查找算法能够手写二分查找代码能够解答一些变化后的考法 算法描述 前提&#xff1a;有已排序数组 A&#xff08;假设已经做好&#xff09; 定义左边界 L、右边界 R&…

SQLite 命令行客户端 + Windows 批处理应用

SQLite 命令行客户端 Windows 批处理应用 下载 SQLite 客户端1. Bat 辅助脚本1. 执行SQL.bat执行 2. 导出Excel.bat执行效果 3. 导出HTML.bat执行效果 4. 清空-订单表.bat 2. 测试 SQL1. 创建订单表.sql2. 插入订单表.sql3. 查询订单表.sql4. 清空订单表.sql5. 删除订单表.sql…

linux驱动编程 - kfifo先进先出队列

简介&#xff1a; kfifo是Linux Kernel里面的一个 FIFO&#xff08;先进先出&#xff09;数据结构&#xff0c;它采用环形循环队列的数据结构来实现&#xff0c;提供一个无边界的字节流服务&#xff0c;并且使用并行无锁编程技术&#xff0c;即当它用于只有一个入队线程和一个出…

黑马的ES课程中的不足

在我自己做项目使用ES的时候&#xff0c;发现了黑马没教的方法&#xff0c;以及一些它项目的小问题 搜索时的匹配方法 这个boolQuery().should 我的项目是通过文章的标题title和内容content来进行搜索 但是黑马它的项目只用了must 如果我们的title和content都用must&#x…