Java线程池

栏目: Java · 发布时间: 7年前

内容简介:Java线程池(以线程池参数最多的构造函数(线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

Java线程池( java.util.concurrent.ThreadPoolExecutor )实现了接口 java.util.concurrent.ExecutorService ,将线程资源缓存起来,实现了线程的复用。

示例代码

package bj;

import io.vavr.control.Try;

import java.time.LocalTime;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.IntStream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/12/7 上午10:05
 */
public class FooTest {

    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(4, 6, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), new ThreadFactory() {
            private int count = 0;

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, String.format("Thread[%d]", ++count));
            }
        }, (r, executor1) -> System.out.println("Ignored: " + r));
        executor.allowCoreThreadTimeOut(true);
        IntStream.range(0, 10).forEach($ -> executor.execute(() -> {
            Try.run(() -> Thread.sleep(1000)).getOrElseThrow((Supplier<RuntimeException>) RuntimeException::new);
            System.out.println(String.format("%s Progress: %d Thread: %s", LocalTime.now(), $, Thread.currentThread().getName()));
        }));
    }
}

示例输出

Ignored: bj.FooTest$$Lambda$3/783286238@27082746
14:13:53.247 Progress: 0 Thread: Thread[1]
14:13:53.247 Progress: 2 Thread: Thread[3]
14:13:53.247 Progress: 8 Thread: Thread[6]
14:13:53.247 Progress: 3 Thread: Thread[4]
14:13:53.248 Progress: 1 Thread: Thread[2]
14:13:53.248 Progress: 7 Thread: Thread[5]
14:13:54.252 Progress: 5 Thread: Thread[6]
14:13:54.252 Progress: 6 Thread: Thread[3]
14:13:54.252 Progress: 4 Thread: Thread[1]

Process finished with exit code 0

线程池各参数讲解

以线程池参数最多的构造函数( java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler) )为例

  • corePoolSize 核心池大小。核心池直接开辟空间
  • maximumPoolSize 最大池(核心池+普通池)大小 线程数量超过这个大小,会拒绝执行
  • keepAliveTime 线程存活时间 线程过了存活时间会自动销毁,默认情况下核心池例外
  • unit 线程存活时间单位
  • workQueue 工作队列 任务会在workQueue排队
  • threadFactory 线程工厂 如何创建线程。可以指定线程名称、记录日志等
  • handler 拒绝执行策略 默认抛异常,不执行

线程池基本工作流程

  1. 创建线程池,核心池分配满线程
  2. 新任务进入,放入核心池,开始执行
  3. 新任务进入,核心池已满,放入执行队列
  4. 新任务进入,执行队列已满,新任务放入普通池立即执行
  5. 新任务进入,线程数量超过最大池大小,拒绝执行
  6. 任务执行完毕,进入等待状态。普通池的线程超时后自动销毁
  7. 如果 allowCoreThreadTimeOut 设为 true ,核心池中的线程超时后自动销毁

示例程序中,各任务的流向

  1. 任务1,放入核心池执行
  2. 任务2,放入核心池执行
  3. 任务3,放入核心池执行
  4. 任务4,放入核心池执行
  5. 任务5,核心池已满,放入执行队列等待
  6. 任务6,核心池已满,放入执行队列等待
  7. 任务7,核心池已满,放入执行队列等待
  8. 任务8,核心池和指定队列都已满,放入普通池立即执行
  9. 任务9,核心池和指定队列都已满,放入普通池立即执行
  10. 任务10, 核心池+普通池已达上限,任务被拒绝执行

线程池任务执行完成后自动销毁全部线程

线程池的存在,默认会阻止主程序的自动退出。销毁掉线程池中的全部线程后,主程序才可以顺利退出。

实现线程池任务全部接触后,自动销毁全部线程,有两种方式:

executor.allowCoreThreadTimeOut(true);
executor.setCorePoolSize(0);

文章首发: https://baijifeilong.github.io


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高扩展性网站的50条原则

高扩展性网站的50条原则

[美] Martin L. Abbott、[美]Michael T. Fisher / 张欣、杨海玲 / 人民邮电出版社 / 2012-6-3 / 35.00元

《高扩展性网站的50条原则》给出了设计高扩展网站的50条原则,如不要过度设计、设计时就考虑扩展性、把方案简化3倍以上、减少DNS查找、尽可能减少对象等,每个原则都与不同的主题绑定在一起。大部分原则是面向技术的,只有少量原则解决的是与关键习惯和方法有关的问题,当然,每个原则都对构建可扩展的产品至关重要。 主要内容包括: 通过克隆、复制、分离功能和拆分数据集提高网站扩展性; 采用横向......一起来看看 《高扩展性网站的50条原则》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器