Javaer,你必须要了解的ExecutorService

2023-05-16

ExecutorService初接触

  之前做的一个功能里有一个耗时操作:处理数据库里对应的记录,然后将每个处理后的结果做个排序。
   恕本人小白,刚开始直接用单线程处理!你敢信?!然后60多万条记录,跑了三分钟才出结果!当时我就震惊了,这尼玛要被“刁”的节奏啊。但我并没有什么好的解决方案,便去咨询老大,然后老大直接丢过来一段代码附带几个字

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

ExecutorService弄个线程池跑

使用了ExecutorService之后,我便爱上了它!!!

简单介绍

  什么是ExecutorService呢?它实现Executor中的方法,jdk中这样介绍它

public interface Executor
执行已提交的 Runnable
 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节、调度等)分离开来的方法。
。。。
此包中提供的 Executor
 实现实现了 ExecutorService
,这是一个使用更广泛的接口。 ThreadPoolExecutor
 类提供一个可扩展的线程池实现。 Executors
 类为这些 Executor 提供了便捷的工厂方法。

使用场景

  关于场景,就拿我最近做的功能举例

无须等待结果

上一篇采集领英信息最后提到采集慢的原因有一个是“使用单线程”,那好,现在使用ExecutorService创建线程池来加快采集速度(代码就不贴了,写一个大概的思路):
- 创建一个线程池ExecutorService executorService = Executors.newCachedThreadPool();该方法创建一个数量没有上限的线程池

  • 将采集代码中for循环的内容抽出来重构为一个集成Thread的类,因为这样可以传递一些参数,类似下面代码
public class CacheThreadPool {
    public static void main(String[] args) {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 15; i++)
            exec.execute(new MyThread("张"+i));
        exec.shutdown();//并不是终止线程的运行,而是禁止在这个Executor中添加新的任务
    }
}

class MyThread extends Thread {

    private String name;

    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println("获取"+name+"的信息并保存");
    }
}

需要注意的是,我for循环中,我不需要等待线程执行结果,因为我不关心每一条是否能成功解析,是否能成功插入数据库。

需要结果

  这个就是开头提到的。现在要开线程跑,但是我不能保证我for循环结束了,每个线程都能返回给我结果,也就是说,我必须要等待线程将60万条数据都处理完,我拿到结果之后,程序才能继续下去。
  jdk里有提供invokeAll方法

 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException;

执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表
这难道就是所谓的“批量执行”?
于是我写了个demo测试了一下,for循环十次,每次处理耗时1s,单线程处理的话就是10s,无可厚非(排除其他一切因素,最理想状态),然后用invokeAll方法批量执行,我预测结果是1s(傻子也猜到了)代码如下:

package com.quick.thread;

import java.util.concurrent.Callable;

/**
 * Created by wangxc on 2017/3/29.
 */
public class TaskSleep implements Callable<Integer> {

    private int num;

    public TaskSleep(int num){
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
//        System.out.println(num + "--->" +i);
        Thread.sleep(1000);
        return  num;
    }
}
package com.quick.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * Created by wangxc on 2017/3/29.
 */
public class ExecutorServiceDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long stat = System.currentTimeMillis();
        ExecutorService executorService = Executors.newCachedThreadPool();
        List<TaskSleep> callList = new ArrayList<TaskSleep>();
        for(int i=0;i<10;i++){
            callList.add(new TaskSleep(i));
        }
        List<Future<Integer>> futures = executorService.invokeAll(callList);
        executorService.shutdown();
        int sum=0;
        for(Future<Integer> item:futures){
            sum += item.get();
        }
        System.out.println("结果"+sum);
        long end = System.currentTimeMillis();
        System.out.println((double)(end-stat)/1000);
    }
}

结果

结果45
1.045

嗯,这就是我想要的结果

最后

ExecutorService使用的方式非常之多,适合自己的业务场景才是最主要的,本文是根据自己的业务需求去使用ExecutorService,仅供参考~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javaer,你必须要了解的ExecutorService 的相关文章

随机推荐

  • python库函数之scipy.signal——滤波器设计

    文章目录 python库函数之scipy signal butter 函数参数设计模拟滤波器设计数字滤波器 2021 06 03 有位博主评论了这篇博客 xff08 评论已被删除 xff09 xff0c 特此说明 python库函数之sci
  • 使用python绘制短时傅里叶变换(STFT)频谱图(时频像)

    文章目录 使用python绘制短时傅里叶变换 xff08 STFT xff09 频谱图 xff08 时频像 xff09 使用python绘制短时傅里叶变换 xff08 STFT xff09 频谱图 xff08 时频像 xff09 使用sci
  • python csv文件数据写入和读取(适用于超大数据量)

    文章目录 python csv文件数据写入和读取 xff08 适用于超大数据量 xff09 python csv文件数据写入和读取 xff08 适用于超大数据量 xff09 一般情况下由于我们使用的数据量比较小 xff0c 因此可以将数据一
  • CentOS 开启端口方法

    查看已经开放的端口 xff1a firewall cmd list ports 查看防火墙状态 xff1a firewall cmd state 开启防火墙 xff1a systemctl start firewalld service 开
  • opencv3颜色识别(C++)

    文章目录 opencv3颜色识别 C 43 43 目标思路1 读取图像2 对比度调整 xff08 直方图均衡 xff09 3 RGB颜色分类4 形态学去噪声 代码结果参考 opencv3颜色识别 C 43 43 目标 给定一幅图像 xff0
  • 小区物业管理系统

    技术 xff1a 小区物业管理 ASP技术 B S 模式 SQL SERVER 2008 摘要 xff1a 随着市场经济的发展和人们生活水平的提高 xff0c 住宅小区已经成为人们安家置业的首选 xff0c 小区业主不但对住宅的本身的美观
  • java判断字符串是否为空的方法总结

    以下是java 判断字符串是否为空的四种方法 方法一 最多人使用的一个方法 直观 方便 但效率很低 if s 61 61 null 34 34 equals s 方法二 比较字符串长度 效率高 是我知道的最好一个方法 if s 61 61
  • 用Python的networkx绘制精美网络图

    最近因为数学建模3天速成Python 然后做了一道网络的题 xff0c 要画网络图 在网上找了一些 xff0c 发现都是一些很基础的丑陋红点图 xff0c 并且关于网络的一些算法也没有讲 xff0c 于是自己进http networkx g
  • Tomcat虚拟路径设置

    前几天写了一个关于登录页面banner图的展示 需求 xff1a banner图的存放地址在项目包的外部 xff0c 不能占用项目资源 这种通过外部存储位置渲染图片的实现方式有两种 xff0c 1 xff1a 目录映射 xff08 虚拟路径
  • Jenkins自动部署,mvn不同的环境打包配置

    今天看了个问题 xff0c 就是在Jenkins里如何根据不同的环境发布代码 我本地的代码环境有 xff0c 开发环境 测试环境 预发布环境和线上环境 基于项目的风险控制 xff0c 安全控制 xff0c 我只有开发环境和测试环境的权限 x
  • IOException while sending message; nested exception is:java.io.FileNotFoundException

    异步发送邮件出现的异常情况 1 问题描述 近期做了一个发送邮件的功能 xff0c 因为在处理发送邮件联系人上出现过失效的邮箱地址 xff0c 为了快速定位到问题 现将批量发送的方式改为单独发送 Failed messages javax m
  • 自定义分页

    给大家介绍一个简单分页的方法 xff08 有兴趣的可以自己试一下 xff09 1 实体 package com hffss entity ext import lombok Builder import lombok Data import
  • SpringBoot请求体中的流只能读取一次的问题HttpServletRequest的流只能读取一次的原因

    问题场景 xff1a 在项目开发过程中需要记录用户的操作行为 xff0c 即用户请求的url和相关url中带有的请求体参数 xff0c 在springboot中只能在拦截器中读取了一次 xff0c 在controller获取不到参数 经过代
  • @PostConstruct注解

    64 PostConstruct 64 PostConstruct注解好多人以为是Spring提供的 xff0c 其实是Java自己的注解 Java中该注解的说明 xff1a 64 PostConstruct该注解被用来修饰一个非静态的vo
  • 天线长度计算

    首先 xff0c 理想天线的长度是半波长 平时说的四分之一波长天线 xff0c 实际上需要考虑 地 才能构成完整的天线 xff0c 也就是我们常说的 非平衡天线 xff1b 天线本身只是天线的一部分 天线长度是波长的四分之一 波长 61 光
  • NFS服务配置、搭建、应用

    一 NFS服务 1 NFS服务只能部署到linux环境而不适用于windows环境 xff0c 说白了就是让不同的机器 不同的系统可以共享彼此的文件 xff08 例如 xff1a windows的共享磁盘一样 xff09 2 NFS原理流程
  • Java 调用Shell脚本执行 SCP命令提示Authorized users only. All activity may be monitored and reported.

    近期做了个小项目主要是关于数据处理这方面的 在Java后端调用服务器上Shell脚本 xff0c 而Shell脚本执行时一条Scp执行结果的提示报 Authorized users only All activity may be moni
  • Java 调用Http和Https接口

    Java调用Http接口和Https接口 大多数我们调用的接口都是Http的 xff0c 很少有Https的接口 xff0c 近期做了个项目就用到和Https接口的请求调用 xff0c 和大家分享一下心得 Http接口和Https接口主要是
  • 多种方式查看电脑是否支持Modern Standby

    控制台查看 CMD输入powercfg a 显示如下有S0 xff0c 则支持Modern Standby 注册表查看 Win 43 R 输入regedit进入注册表 xff0c 查看HKEY LOCAL MACHINE SYSTEM Cu
  • Javaer,你必须要了解的ExecutorService

    ExecutorService初接触 之前做的一个功能里有一个耗时操作 xff1a 处理数据库里对应的记录 xff0c 然后将每个处理后的结果做个排序 恕本人小白 xff0c 刚开始直接用单线程处理 xff01 你敢信 xff1f xff0