① java一般是如何定义一个线程池的?请看代码

private static ExecutorService taskPool = new ThreadPoolExecutor(16, 32
,200L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1000),new ThreadFactoryBuilder()
.setNameFormat("thread-自定义线程名-runner-%d").build());

注:这里的线程池中的参数后续会做介绍 ,你只需要知道 16是核心线程数、32是最大线程数即可。

② 那如何往线程池中加入任务呢?请看代码

public static void main(String[] args) {taskPool.submit(new Runnable() {@Overridepublic void run() {// 你要在线程池中执行的代码...}});}

submit方法中传入一个 Runnable对象即可, 是不是很简单,但是一般不是直接new 一个Runnable丢进线程池的,而是写一个类 ,去实现 Runnable,代码如下:

public class ATask implements Runnable {private String a;public ATask(String a) {this.a = a;}public ATask() {}@Overridepublic void run() {// 写下你要在线程池中执行的代码...System.out.println("a=" + a);}
}

还没完 我经常需要在任务里面注入spring中的service 一般怎么处理呢?

来看代码 ,目标是把AService注入到ATask中并且调用它:

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;class B {private static ExecutorService taskPool = new ThreadPoolExecutor(16,32,200L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1000),new ThreadFactoryBuilder().setNameFormat("thread-thirdPushMsgJob-runner-%d").build());// ① 在调用线程池之前注入AService到当前类@Autowiredprivate AService aService;public static void main(String[] args) {// ② 将AService传入ATask中ATask aTask = new ATask("aStr", aService);// 任务提交到线程池taskPool.submit(aTask);}
}public class ATask implements Runnable {private String a;private AService aService;// ③ 对应的ATask需要一个包含 AService的构造函数public ATask(String a, AService aService) {this.a = a;this.aService = aService;}public ATask() {}@Overridepublic void run() {// 写下你要在线程池中执行的代码...// ④ 执行AService中的a()方法aService.a();}
}

注:上述线程池不能说是完美,但是也符合大多数使用场景了,但如果我想要获取线程池任务的处理结果怎么办呢?

③ 获取线程池的处理结果

3.1 首先多线程的任务不能再是实现 Runnable,而是实现Callable<T>,因为Callable才允许线程任务返回结果,我们来看代码:

// ① 实现Callable接口 【接口泛型即为线程的返回类型】
public class ATask implements Callable<Object> {private String a;public ATask(String a) {this.a = a;}public ATask() {}@Overridepublic Object call() throws Exception {// ② 你要在线程池中执行的代码...return "你线程任务的返回值";}
}

注:可以看到 ATask得call方法已经有返回值了 那怎么获取这个返回值呢

3.2 获取线程得返回值

class B {private static ExecutorService taskPool = new ThreadPoolExecutor(16,32,200L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(1000),new ThreadFactoryBuilder().setNameFormat("thread-thirdPushMsgJob-runner-%d").build());public static void main(String[] args) throws
ExecutionException, InterruptedException {ATask aTask = new ATask("aStr");// 任务提交到线程池Future<Object> future = taskPool.submit(aTask);// 获取任务返回结果Object result = future.get();System.out.println(result);}
}

只需要接收submit方法的返回值 再get即可获取数据,需要注意的是  future.get()有可能出现异常,建议try-catch处理 future.get(),防止未知异常的出现导致线程任务未正确返回结果

④ 线程池的参数怎么调优?

来看看线程池中参数的释义:

那这些线程池参数都啥意思呢?我们来看

1. 核心线程数:有任务来了,判断到当前任务数量小于核心线程数时,就新建一个线程而不是把任务放入队列

2.最大线程数和任务队列:有任务来了,判断当前任务大于核心线程数时,就会往队列里面存放任务,只有当任务队列满了,才会创建新的线程来处理任务,但是线程池最多能有多少个任务是由最大线程数来决定的。 那在这里问问,最大线程数和任务队列都满了怎么破呢? 有个 线程池饱和策略 建议大家去搜索看,网上有很多讲的很好,我就不详讲了。

java使用线程池执行任务相关推荐

  1. Java等线程池执行完所有任务后再执行主线程

    2019独角兽企业重金招聘Python工程师标准>>> 因为要定时往数据库插入上百万数据,插入完之后再修改另外一部分数据, 怎么在线程池执行完所有任务后再执行主线程呢 import ...

  2. Java多线程- 线程池的基本使用和执行流程分析 - ThreadPoolExecutor

    线程池的实现原理 池化技术 一说到线程池自然就会想到池化技术. 其实所谓池化技术,就是把一些能够复用的东西放到池中,避免重复创建.销毁的开销,从而极大提高性能. 常见池化技术的例如: 线程池 内存池 ...

  3. 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )

    文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...

  4. java 线程池的使用_Java 使用线程池执行若干任务

    在执行一系列带有IO操作(例如下载文件),且互不相关的异步任务时,采用多线程可以很极大的提高运行效率.线程池包含了一系列的线程,并且可以管理这些线程.例如:创建线程,销毁线程等.本文将介绍如何使用Ja ...

  5. Java 监控线程池所有任务是否执行完毕

    Java 监控线程池所有任务是否执行完毕 场景引入 在最近的工作中遇到一个需要批量生产百万数据并写入数据库的需求,先通过单线程的方式去实现,但是感觉效率一般,然后通过多线程的方式去改进,但是遇到下面的 ...

  6. java 等待线程/线程池执行完毕

    1.单线程开始并执行完毕 当线程开始后,需要用到join的方法 不废话直接贴代码 public static void main(String args[]) {long begin = System ...

  7. 探索JAVA并发 - 线程池详解

    作者:acupt,80后资深Java工程师一枚!架构师社区合伙人! 线程池是并发编程中必不可少的一种工具,也是面试高频话题. 线程池,即管理着若干线程的资源池(字面意思).相比于为每个任务分配一个线程 ...

  8. Java Review - 线程池中使用ThreadLocal不当导致的内存泄漏案例源码分析

    文章目录 概述 Why 内存泄露 ? 在线程池中使用ThreadLocal导致的内存泄漏 概述 ThreadLocal的基本使用我们就不赘述了,可以参考 每日一博 - ThreadLocal VS I ...

  9. 谈谈java的线程池(创建、机制)

    目录 Executors创建线程池默认方法 自定义线程池 Executors创建线程池默认方法 newFixedThreadPool()方法,该方法返回一个固定数量的线程池,该方法的线程数始终不变,当 ...

最新文章

  1. echo mysql_mysql select
  2. java面向对象第四章上机_java面向对象第四章
  3. C语言中低位存放,C语言 大端小端存储解析以及判断方法
  4. MySQL如何添加主键(PRIMARY KEY)
  5. .NET Core UI框架Avalonia
  6. java设计模式之装饰模式_Java中的装饰器设计模式
  7. 「工具」PWA Manifest图标及 favicon.ico 生成工具
  8. Apollo 分布式配置中心 搭建篇
  9. 台式计算机windows7系统怎么做,台式电脑怎么在线进行重装win7系统
  10. oracle 修改 回话数,Oracle命令--修改oracle回话数
  11. 设计灵感|资讯博客类App界面设计
  12. 一篇文章让你学透Linux系统中的more命令
  13. Installation of Requests
  14. 将一幅图像转换为灰度图
  15. nodeJS 视频教程
  16. Android11.0 V-A/B无缝OTA升级update_engine
  17. 从《Java核心编程》纵览Java全貌
  18. LeetCode 954. 二倍数对数组
  19. 【原创题】皮卡丘的兄弟姐妹
  20. C语言stdlid是什么函数,为什么Curry的std lib中的非确定性选择函数没有直接定义,而是使用辅助2参数函数?...

热门文章

  1. Python递归算法详解
  2. java动态代理原理剖析
  3. PHP怎么实现游戏玩家匹配,多人pvp玩法匹配算法的简单实现
  4. [问题2014A13] 解答
  5. Python版在图片中添加文字
  6. 每次听到同事跳槽后的薪资,我就像打了鸡血一样
  7. 【转载】VBoxManage相关命令
  8. 谈什么是卡片式设计?
  9. 包含ES6所有数组方法
  10. English,The Da Vinci Code,Chapter 5