iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >java中线程池最实用的创建与关闭指南
  • 620
分享到

java中线程池最实用的创建与关闭指南

2024-04-02 19:04:59 620人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录前言线程池创建 只需要执行shutdown就可以优雅关闭 执行shutdownNow关闭的测试 总结前言 在日常的开发工作当中,线程池往往承载着一个应用中最重要的业务逻辑,因此我

前言

在日常的开发工作当中,线程池往往承载着一个应用中最重要的业务逻辑,因此我们有必要更多地去关注线程池的执行情况,包括异常的处理和分析等。

线程池创建

避免使用Executors创建线程池,主要是避免使用其中的默认实现,那么我们可以自己直接调用ThreadPoolExecutor的构造函数来自己创建线程池。在创建的同时,给BlockQueue指定容量就可以了。


private static ExecutorService executor = new ThreadPoolExecutor(10, 10,
        60L, TimeUnit.SECONDS,
        new ArrayBlockingQueue(10));

这种情况下,一旦提交的线程数超过当前可用线程数时,就会抛出java.util.concurrent.RejectedExecutionException,这是因为当前线程池使用的队列是有边界队列,队列已经满了便无法继续处理新的请求。但是异常(Exception)总比发生错误(Error)要好。

除了自己定义ThreadPoolExecutor外。还有其他方法。这个时候第一时间就应该想到开源类库,如apache和guava等。

推荐使用guava提供的ThreadFactoryBuilder来创建线程池。


public class ExecutorsDemo {
 
    private static ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
        .setNameFORMat("demo-pool-%d").build();
 
    private static ExecutorService pool = new ThreadPoolExecutor(5, 200,
        0L, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
 
    public static void main(String[] args) {
 
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            pool.execute(new SubThread());
        }
    }
}


只需要执行shutdown就可以优雅关闭


package com.zxd.concurrent;

import com.Google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


    public static void main(String[] args) {
        // TODO 如何正确优雅简单的关闭线程池 ,无须其他多余操 ;创建线程池我选择用这种方法比较可靠
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        //接收处理数据的结果集合
        List<Integer> resList = Lists.newArrayList();
        //开启的任务 我们设置的核心处理线程数5个所以 会有多出来的线程在队列中等待
        for (int i = 0; i < 30; i++) {
            executor.execute(new Task(i, resList));
        }
        //1、关闭线程池 一定要在循环结束关闭
        //2、这个关闭方法不会立即关闭所有在执行的任务线程,
        executor.shutdown();
        //4.这里是检查线程池是否所有任务都执行完毕关闭
        int j = 0;
        while (true) {
            //5.这里是等线程池彻底关闭以后做的判断 保证所有线程池已经全部关闭退出while循环
            if (executor.isTerminated()) {
                System.out.println("所有线程已经运行完毕:" + j);
                break;
            }
            // 为避免一直循环 加个睡眠
            try {
                //如果执行shutdown方法没有关闭的线程池线程池会尝试关闭
                System.out.println("尝试关闭线程次数:" + j);
                j++;
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        //FIXME 3、下面的方法会立即关闭线程池,没有执行完的也不会在执行了,如果有等待队列的任务也不会继续执行
        System.out.println("【完成的总线程数】:" + resList.size());

    }

    static class Task implements Runnable {
        int name;

        List<Integer> list;

        public Task(int name, List<Integer> list) {
            this.name = name;
            this.list = list;
        }

        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                int j = i * 10;
                // 做业务处理
                //System.out.println("task " + name + " is running");
            }
            list.add(name + 1);
            System.out.println("task " + name + " is over");
        }
    }

}

输出结果

task 0 is over
task 3 is over
task 1 is over
task 2 is over
task 7 is over
task 6 is over
task 5 is over
尝试关闭线程次数:0
task 10 is over
task 9 is over
task 4 is over
task 8 is over
task 14 is over
task 13 is over
task 12 is over
task 11 is over
task 18 is over
task 17 is over
task 16 is over
task 15 is over
task 22 is over
task 21 is over
task 20 is over
task 19 is over
task 26 is over
task 25 is over
task 24 is over
task 23 is over
task 29 is over
task 28 is over
task 27 is over
所有线程已经运行完毕:1
【完成的总线程数】:30

执行shutdownNow关闭的测试


package com.zxd.concurrent;

import com.google.common.collect.Lists;

import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPool {


    public static void main(String[] args) {
        // TODO 如何正确优雅简单的关闭线程池 ,无须其他多余操 ;创建线程池我选择用这种方法比较可靠
        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        //接收处理数据的结果集合
        List<Integer> resList = Lists.newArrayList();
        //开启的任务 我们设置的核心处理线程数5个所以 会有多出来的线程在队列中等待
        for (int i = 0; i < 200; i++) {
            executor.execute(new Task(i, resList));
        }
        //1、关闭线程池 一定要在循环结束关闭
        //2、这个关闭方法不会立即关闭所有在执行的任务线程,
//        executor.shutdown();
        //FIXME 3、下面的方法会立即关闭线程池,没有执行完的也不会在执行了,如果有等待队列的任务也不会继续执行
        List<Runnable> list = executor.shutdownNow();
        System.out.println("c剩余的没有执行的任务【线程数】= " + list.size());
        System.out.println("【完成的总线程数】:" + resList.size());
        //4.这里是检查线程池是否所有任务都执行完毕关闭
        int j = 0;
        while (true) {
            //5.这里是等线程池彻底关闭以后做的判断 保证所有线程池已经全部关闭退出while循环
            if (executor.isTerminated()) {
                System.out.println("所有线程已经运行完毕:" + j);
                break;
            }
            // 为避免一直循环 加个睡眠
            try {
                //如果执行shutdown方法没有关闭的线程池线程池会尝试关闭
                System.out.println("尝试关闭线程次数:" + j);
                j++;
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    static class Task implements Runnable {
        int name;

        List<Integer> list;

        public Task(int name, List<Integer> list) {
            this.name = name;
            this.list = list;
        }

        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                int j = i * 10;
                // 做业务处理
                //System.out.println("task " + name + " is running");
            }
            list.add(name + 1);
            System.out.println("task " + name + " is over");
        }
    }

}

输出结果

总结

到此这篇关于java中线程池最实用的创建与关闭的文章就介绍到这了,更多相关java线程池创建与关闭内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: java中线程池最实用的创建与关闭指南

本文链接: https://www.lsjlt.com/news/135167.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java中线程池最实用的创建与关闭指南
    目录前言线程池创建 只需要执行shutdown就可以优雅关闭 执行shutdownNow关闭的测试 总结前言 在日常的开发工作当中,线程池往往承载着一个应用中最重要的业务逻辑,因此我...
    99+
    2024-04-02
  • Java中的异步与线程池怎么创建使用
    这篇文章主要介绍“Java中的异步与线程池怎么创建使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java中的异步与线程池怎么创建使用”文章能帮助大家解决问题。初始化线程的4种方式1.继承Thre...
    99+
    2023-07-04
  • java中线程池创建的方式有哪些
    本篇文章为大家展示了java中线程池创建的方式有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发;3. 客户端开...
    99+
    2023-06-14
  • 线程池在 Java 程序中的最佳实践
    线程池中的线程数应根据应用程序的特定需求确定。 过少的线程可能会导致性能问题,而过多的线程又会浪费资源。 理想的线程数通常与应用程序并发需求成正比。 2. 使用适当的线程池类型 固定大小线程池:用于处理稳定且可预测的工作负载。 可伸...
    99+
    2024-03-13
    线程池
  • 怎么在java中使用ThreadPoolExecutor创建一个线程池
    这篇文章给大家介绍怎么在java中使用ThreadPoolExecutor创建一个线程池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Java可以用来干什么Java主要应用于:1. web开发;2. Android开发...
    99+
    2023-06-14
  • Java 线程池并发编程的最佳实践与技巧
    使用 Executors 工厂方法创建线程池,以确保最佳性能和可伸缩性。 选择合适的线程池类型(例如,FixedThreadPool、CachedThreadPool、ScheduledThreadPool)以满足应用程序需求。 根据应...
    99+
    2024-03-13
    线程池
  • 详解Java线程池的使用(7种创建方法)
    目录 1. 固定数量的线程池a.  线程池返回结果b. ⾃定义线程池名称或优先级2. 带缓存的线程池3. 执⾏定时任务 a.&nbs...
    99+
    2023-03-24
    Java线程池 Java线程池使用 线程池
  • Java Swing实战指南:创建交互式应用程序
    Java Swing 是一个健壮且可扩展的 GUI 库,用于创建跨平台的桌面应用程序。本指南将指导您使用 Swing 创建交互式且用户友好的应用程序。 1. Swing 组件简介 容器: 容纳其他组件的组件,如 JFrame、JPane...
    99+
    2024-04-02
  • java中多线程与线程池的基本使用方法
    目录前言继承Thread 实现Runnale接口Callable线程池常见的4种线程池。总结前言 在java中,如果每个请求到达就创建一个新线程,开销是相当大的。在实际使用中,服务器...
    99+
    2024-04-02
  • Java线程创建与Thread类的使用方法
    目录1.线程与Thread类1.1操作系统中的线程与Java线程1.1.1线程与Thread类1.1.2Thread类的构造方法1.1.3启用java线程必会的方法1.2第一个Jav...
    99+
    2024-04-02
  • Vue3中watch的用法与最佳实践指南
    目录前言🌟一、API介绍二、监听多个数据源三、侦听数组四、侦听对象五、总结✨前言🌟 本文以实验的形式,为大家揭示Vue3中watch的...
    99+
    2024-04-02
  • PHP中关闭伪静态代代码的实用指南
    PHP中关闭伪静态代代码的实用指南 随着网站开发的不断发展,伪静态代代码(URL Rewrite)在提高网站用户体验和搜索引擎优化方面起到了重要作用。然而,在某些情况下,关闭伪静态代代...
    99+
    2024-04-02
  • Java中的线程如何实现通过关闭Socket终止
    这篇文章将为大家详细讲解有关Java中的线程如何实现通过关闭Socket终止,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。具体内容如下package Threads;import java....
    99+
    2023-05-31
    java socket 终止线程
  • Lambda 的实战指南:Java 中的函数式编程应用
    Lambda 表达式是 Java 8 中引入的一项重要特性,它允许开发人员将函数作为参数传递。这使得在 Java 中实现函数式编程成为可能,函数式编程是一种强调不变性、纯净性和不可变性的编程范式。 优点 使用 Lambda 表达式提供了以...
    99+
    2024-04-02
  • 如何在使用golang创建的wasm中实现多线程?
    积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《如何在使用golang创建的was...
    99+
    2024-04-05
  • 构建高可用的MySQL集群:主从复制与负载均衡的最佳实践指南
    构建高可用的MySQL集群:主从复制与负载均衡的最佳实践指南近年来,随着互联网的快速发展,数据库已成为大部分Web应用的核心数据存储和处理引擎之一。在这个场景下,高可用性和负载均衡成为了数据库架构设计中的重要考虑因素。而MySQL作为最受欢...
    99+
    2023-10-22
    主从复制 负载均衡 MySql集群
  • 重定向入门指南:Java和Linux教程中的实用技巧!
    重定向是一种常用的技术,可以将一个命令的输出重定向到文件或另一个命令的输入。在Java和Linux中,重定向被广泛应用。本文将介绍Java和Linux中的重定向技术,并提供实用的技巧和演示代码。 一、在Java中使用重定向 在Java中,...
    99+
    2023-06-04
    linux 教程 重定向
  • Java Apache Camel 实践指南:构建高可靠性的消息驱动的应用程序
    Apache Camel 简介 Apache Camel 是一个开源的集成框架,用于在不同的系统之间进行消息的路由、转换和处理。它支持多种消息协议,如 AMQP、JMS、HTTP、文件系统等,并提供了丰富的组件和连接器,可以轻松地集成不...
    99+
    2024-02-10
    消息驱动架构 Apache Camel 可靠性 性能
  • 在 Java 中优雅地移除字符串最后一个字符:不同级别程序员的实践指南
    引言: 处理字符串是编程中非常常见的任务。本文将详细介绍四种在 Java 中优雅地移除字符串最后一个字符的方法,并针对不同级别的程序员进行讨论。我们将从简单的方法入手,逐步介绍更高级的技术,以帮助程序员根据自己的水平和需求选择最合适的解决方...
    99+
    2023-09-01
    java 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作