ExecutorService线程池的创建、钩子、销毁等相关操作

创建线程池

执行说明

图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LFqUk3NT-1596622459415)(https://static.phpisfuture.com/futureblog/article/20200316152436894.png)]

步骤

  • 1、创建线程池对线时候不会创建线程,当有第一个线程任务时,才会创建线程。
  • 2、如果线程数少于核心线程数时,当有新的线程来,不管之前的线程是否空闲,都会继续创建新的线程,直到达到核心线程数。
  • 3、当线程数等于核心线程数时,当有新线程来,先放入任务队列中等待核心线程执行完毕之后取出任务队列中任务执行,直到线程队列达到最大容量。
  • 4、当线程数大于队列最大容量时候,会创建非核心线程来执行任务,直到达到最大线程数(maximumPoolSize)。
  • 5、当线程数等于最大线程数时,触发线程池拒绝策略(RejectedExecutionHandler)。

例子

corePoolSize为5,maximumPoolSize为10,workQueue的size为100。
当请求来时,最多创建5个核心线程来执行任务,剩下的被添加到任务队列,当队列慢了后会创建非核心线程执行任务直到10个,再来任务就拒绝。

构造函数

ExecutorService executorService = new ThreadPoolExecutor(
        int corePoolSize,
        int maximumPoolSize,
        long keepAliveTime,
        TimeUnit unit,
        BlockingQueue<Runnable> workQueue,
        ThreadFactory threadFactory,
        RejectedExecutionHandler handler);

参数说明:

  • corePoolSize:核心线程数。一旦创建,就不会被释放销毁。
  • maximumPoolSize:最大线程数。线程池允许创建的最大线程数量。
  • keepAliveTime:线程空闲时间。达到这个时间非核心线程将会被回收销毁。(allowCoreThreadTimeOut修改这个属性为ture,核心线程也会被回收)
  • unit:线程空闲时间单位。
  • workQueue:任务队列。当任务对大于核心线程时候,就会被放到这个队列中等待。
  • threadFactory:线程工厂。创建新线程时,通过线程工厂来创建。
  • handler:线程池拒绝策略。

workQueue任务队列

SynchronousQueue:同步阻塞单一队列

该队列put之后会阻塞当前线程,阻塞到等有别的线程来拿走。同步队列没有任何内部容量。不要使用add,因为这个队列内部没有任何容量,所以会抛出异常“IllegalStateException”。翻译一下:这是一个内部没有任何容量的阻塞队列,任何一次插入操作的元素都要等待相对的删除/读取操作,否则进行插入操作的线程就要一直等待,反之亦然。

不需要队列存储的时候就会使用这种,比如Executors.newCachedThreadPool()。

示例:

package com.weilai;

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

/**
 * @author weilai
 * @email 352342845@qq.com
 * @date 2019-12-02 10:53
 */
public class ThreadLocalTest {
   

    public static void main(String[] args) {
   
        SynchronousQueue<String> queue = new SynchronousQueue<>();
        // 不要使用add,因为这个队列内部没有任何容量,所以会抛出异常“IllegalStateException”
        // queue.add(new Object());
        ExecutorService service = Executors.newSingleThreadExecutor();
        service.submit( () -> {
   
            try {
   
                Thread.sleep(3000);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            String poll = queue.poll();
            System.out.println(poll);
        });
        try {
   
            System.out.println(1);
            // 操作线程会在这里被阻塞,直到有其他操作线程取走这个对象
            queue.put("hello");
            System.out.println(2);
        } catch (InterruptedException e) {
   
            e.printStackTrace
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!对于基于 ExecutorService 线程池工具类的问题,我可以给你一些基本的解释和用法示例。 ExecutorServiceJava 提供的一个线程池工具类,它可以帮助我们管理和执行线程任务。它的主要作用是重用线程,减少线程创建销毁的开销,提高程序的性能。 首先,我们需要创建一个 ExecutorService 实例。可以使用 Executors 类的静态方法来创建不同类型的线程池,比如: ```java ExecutorService executorService = Executors.newFixedThreadPool(5); ``` 上面的代码创建了一个固定大小为 5 的线程池。你也可以根据需求选择其他类型的线程池,比如 CachedThreadPool、SingleThreadExecutor 等。 接下来,我们可以向线程池提交任务。可以通过调用 `submit()` 方法来提交一个 Callable 或 Runnable 对象,例如: ```java executorService.submit(new Callable<String>() { @Override public String call() throws Exception { // 在这里编写需要执行的任务逻辑 return "任务执行结果"; } }); ``` 或者使用 Lambda 表达式简化代码: ```java executorService.submit(() -> { // 在这里编写需要执行的任务逻辑 return "任务执行结果"; }); ``` 提交任务后,线程池会自动分配一个可用的线程去执行任务,并返回一个 Future 对象,可以用来获取任务的执行结果。 最后,当我们不再需要线程池时,可以调用 `shutdown()` 方法来关闭线程池: ```java executorService.shutdown(); ``` 这会等待已提交的任务执行完毕,并停止接受新的任务。 以上就是基于 ExecutorService 线程池工具类的基本用法。希望对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值