当前位置: 首页 > article >正文

如何创建一个线程池

如何创建一个线程池

线程池主要使用ThreadPoolExecutorScheduledThreadPoolExcutor来创建

ThreadPoolExecutor

ThreadPoolExecutor一共有四个构造方法

image-20250128161612108

参数介绍

参数描述
corePoolSize核心线程数
maximumPoolSize最大线程数
keepAliveTime线程存活时间
unit时间单位
workQueue工作队列
threadFactory线程工厂
handler任务拒绝策略

参数含义

corePoolSizemaximumPoolSizekeepAliveTimeunit
3510TimeUnit.SECOUNDS

image-20250128171029111

非核心线程没有任务并且达到存活时间就会被销毁

核心线程:线程池不关闭就不会被销毁

工作队列workQueue

没执行的任务都是在这里排队,线程池的线程会从这里去拿任务

线程工厂ThreadFactory

线程工厂可以执行线程如何生产线程,设置自定义线程名称,线程优先级,线程类型等

public class ThreadFActory implement THreadFactory{
    
    @Override
    Thread new THread(Runnable r){
        Thread t = new THread(r);
        t.setName("..");
        t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
    
}

任务拒绝策略handler

  • 情况一:核心线程数和非核心线程数已满
  • 情况二:线程池的线程都在忙碌
  • 情况三:任务队列已满
  • 情况四:线程池无法扩容

满足以上四种情况的时候,这个任务就会被拒绝

线程拒绝策略方式:

任务拒绝策略描述
AbortPolicy默认拒绝策略,抛出RejectedExecutionException异常
DiscardPolicy直接丢弃任务
DiscardOldestPolicy丢弃处于任务头部任务,添加被拒绝任务
CallerRunsPolicy使用调用者线程直接执行被拒绝任务

最后,使用原生线程创建线程池代码如下:

该代码会按顺序打印出1-100

package com.javaclimb.test;

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

public class Main {
    static final int n = 1;

    public static void main(String[] args) {
        MyNumber myNumber = new MyNumber();
        Task1 task1 = new Task1(myNumber);
        //创建线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10, 1,
                TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(), new MyThreadFactory("task"));
        //10个任务提交给线程池
        for (int i = 1; i <= 10; i++) {
            threadPoolExecutor.execute(task1);
        }
        //关闭线程池
        threadPoolExecutor.shutdown();
    }
}

//线程工厂
class MyThreadFactory implements ThreadFactory {
    private int count = 1;
    private String prefix;

    public MyThreadFactory(String prefix) {
        this.prefix = prefix;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setName(prefix + "-" + count++);
        thread.setPriority(Thread.NORM_PRIORITY);
        return thread;
    }
}

class MyNumber {
    public  Integer n = 1;
    public  Boolean f = false;
}

class Task implements Runnable {
    private final MyNumber myNumber;
    public Task(MyNumber myNumber) {
        this.myNumber = myNumber;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (myNumber) {
                if (myNumber.n == 100) {
                    if(!myNumber.f)System.out.println(Thread.currentThread().getName()+"->" + myNumber.n);
                    myNumber.f = true;
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"->" + myNumber.n);
                myNumber.n++;
            }
        }
    }
}

执行结果也可以看到是没问题的

image-20250128183031778


http://www.kler.cn/a/524442.html

相关文章:

  • 【后端】Flask
  • 升级到Mac15.1后pod install报错
  • 1.26学习
  • 使用 Redis 实现分布式锁的基本思路
  • MySQL(单表访问)
  • 【Docker】快速部署 Nacos 注册中心
  • DeepSeek核心贡献:将SFT和RL统一的数学公式
  • C# INotifyPropertyChanged接口在list类型中的应用
  • 大一计算机的自学总结:异或运算
  • 大数据相关职位介绍之一(数据分析,数据开发,数据产品经理,数据运营)
  • 【go语言】函数
  • springboot基于SpringBoot的养老院管理系统设计与实现
  • RDK X5运行DeepSeek-R1-Distill-Qwen-1.5B,体验长思维链的语言大模型!
  • 芯片AI深度实战:基础篇之Ollama
  • GAEA 社区:从用户到共同创造者
  • 线程概念、操作
  • Python NumPy(6):修改数组形状、翻转数组、修改数组维度
  • MySQL查询优化(三):深度解读 MySQL客户端和服务端协议
  • 网站如何正式上线(运维详解)
  • 解决 pip install 出现 error: subprocess-exited-with-error 错误的方法
  • 小黑日常积累:学习了CROSS APPLY字段,将sqlserver中字段通过分隔符拆分并统计
  • “爱”之浅谈(一)
  • 混合专家模型MoE的全面详解
  • MybatisX插件快速创建项目
  • [C语言日寄] <stdio.h> 头文件功能介绍
  • Go学习:字符、字符串需注意的点