Java 线程池 参数

1、为什么要使用线程池

线程池能有效管控线程,统一分配任务,优化资源使用。

2、线程池的参数

创建线程池,在构造一个新的线程池时,必须满足下面的条件:

corePoolSize(线程池基本大小)必须大于或等于0;
maximumPoolSize(线程池最大大小)必须大于或等于1;
maximumPoolSize必须大于或等于corePoolSize;
keepAliveTime(线程存活保持时间)必须大于或等于0;
workQueue(任务队列)不能为空;
threadFactory(线程工厂)不能为空,默认为DefaultThreadFactory类(可以通过线程工厂对不同线程池的线程名称进行设置,以区分产生bug的线程是哪个池的)
handler(线程饱和策略)不能为空,默认策略为ThreadPoolExecutor.AbortPolicy。

线程池参数围绕两个核心,线程任务

线程相关的参数:核心线程数,最大线程数,线程存活保持时间,线程饱和策略,线程工厂。

任务相关的参数:任务队列。

3、线程池执行过程

1、创建核心线程处理任务,失败则继续

2、将任务添加到任务队列

3、创建非核心线程处理任务

4、线程饱和策略

4、核心参数分析

4.1 任务队列

4.1.1 直接提交队列SynchronousQueue

设置为SynchronousQueue队列,SynchronousQueue是一个特殊的BlockingQueue,它没有容量,每执行一个插入操作就会阻塞。一般使用SynchronousQueue都会要求为无界(maximumPoolSize=Integer.MAX_VALUE)。

public class PoolTask implements Runnable{
    public int i;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 正在执行 " + i + " 号任务");
    }

    public PoolTask(int i) {
        this.i = i;
    }
}
    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new SynchronousQueue<>());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            threadPoolExecutor.execute(poolTask);
        }
        threadPoolExecutor.shutdown();

    }

执行结果:


4.1.2 有界的任务队列ArrayBlockingQueue

一般使用ArrayBlockingQueue来实现。使用ArrayBlockingQueue有界任务队列,若有新的任务需要执行时,线程池会创建新的线程,直到创建的线程数量达到corePoolSize时,会将新的任务加入到等待队列中。这里等待队列的任务数量设置为2,若等待队列已满,即超过ArrayBlockingQueue初始化的容量,则继续创建线程,直到线程数量达到maximumPoolSize设置的最大线程数量,若大于maximumPoolSize,则执行拒绝策略。

    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2));
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            threadPoolExecutor.execute(poolTask);
        }
        threadPoolExecutor.shutdown();
    }

执行结果:

4.1.3 无界的任务队列LinkedBlockingQueue

一般使用LinkedBlockingQueue来实现。使用无界的任务队列,线程池的任务队列可以无限制添加新任务,而线程池创建的最大线程数就是corePoolSize设置的数量,这种情况下maximumPoolSize设置的值是不会生效的,就算等待队列中有许多未执行的任务,线程池的数量达到了corePoolSize的值后也不会增加新的线程。

    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            threadPoolExecutor.execute(poolTask);
        }
        threadPoolExecutor.shutdown();
    }

运行结果:


4.1.4 优先任务队列PriorityBlockingQueue

一般使用PriorityBlockingQueue来实现。任务需要实现comparable接口,根据任务的优先级执行任务。

public class PoolTask implements Runnable, Comparable<PoolTask>{
    public int i;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 正在执行 " + i + " 号任务");
    }

    public PoolTask(int i) {
        this.i = i;
    }

    @Override
    public int compareTo(PoolTask o) {
        //升序排序
        return o.getI() - this.getI();
    }
}
    public static void main(String[] args) {

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new PriorityBlockingQueue<>());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            threadPoolExecutor.execute(poolTask);
        }
        threadPoolExecutor.shutdown();
    }

运行结果:

4.2 线程饱和策略

4.2.1 ThreadPoolExecutor.AbortPolicy

线程池默认的阻塞策略。不执行此任务,而且抛出一个运行时异常(未检查的异常RejectedExecutionException)。

切记:ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。

ThreadPoolExecutor.DiscardPolicy

不执行此任务,而且不抛异常。(是个空方法)

public class PoolTask implements Runnable, Comparable<PoolTask>{
    public int i;

    public int getI() {
        return i;
    }

    public void setI(int i) {
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " 正在执行 " + i + " 号任务");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public PoolTask(int i) {
        this.i = i;
    }

    @Override
    public int compareTo(PoolTask o) {
        //升序排序
        return o.getI() - this.getI();
    }
}
public class PoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            try {
                threadPoolExecutor.execute(poolTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        threadPoolExecutor.shutdown();
    }
}

运行结果:

4.2.2 ThreadPoolExecutor.DiscardOldestPolicy

从队列里删除最老的任务(头部的一个任务),并再次execute 此task。

public class PoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardOldestPolicy());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            try {
                threadPoolExecutor.execute(poolTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        threadPoolExecutor.shutdown();
    }
}

运行结果:

4.2.3 ThreadPoolExecutor.CallerRunsPolicy

让调用execute方法的线程执行此command,会阻塞入口。

这是个调节机制,既不抛弃任务也不抛出异常,而是将某些任务回退到调用者,让调用者所在的线程去执行。

public class PoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            try {
                threadPoolExecutor.execute(poolTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        threadPoolExecutor.shutdown();
    }
}

运行结果:

4.2.4 用户自定义拒绝策略(最常用)

实现RejectedExecutionHandler,并自己定义策略模式

package com.example.dyc.mythreadpool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

public class MyThreadPolicy implements RejectedExecutionHandler {
    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        if (r instanceof PoolTask){
            PoolTask poolTask = (PoolTask) r;
            if (poolTask.getI() != 6){
                return;
            }
            System.out.println("获取到六号任务,试图放入队列");
            BlockingQueue<Runnable> queue = executor.getQueue();
            while (true) {
                if (queue.remainingCapacity() > 0) {
                    queue.add(poolTask);
                    System.out.println("放入队列成功");
                    break;
                } else {
                    try {
                        System.out.println("放入队列失败,继续试图放入");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }
}
public class PoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 2, 5000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(), new MyThreadPolicy());
        for (int i = 0; i < 10; i++) {
            PoolTask poolTask = new PoolTask(i);
            try {
                threadPoolExecutor.execute(poolTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        threadPoolExecutor.shutdown();
    }
}

运行结果:

5 常用线程池类型

java通过Executors提供四种线程池,分别为:

5.1 newCachedThreadPool


newCachedThreadPool创建一个可缓存的无界线程池,如果线程池长度超过处理需要,可灵活回收空线程,若无可回收,则新建线程。当线程池中的线程空闲时间超过60s,则会自动回收该线程,当任务超过线程池的线程数则创建新的线程,线程池的大小上限为Integer.MAX_VALUE,可看作无限大。


5.2 newFixedThreadPool


newFixedThreadPool创建一个指定大小的线程池,可控制线程的最大并发数,超出的线程会在LinkedBlockingQueue阻塞队列中等待。


5.3 newScheduledThreadPool

newScheduledThreadPool线程池支持定时以及周期性执行任务,创建一个corePoolSize为传入参数,最大线程数为整形的最大数的线程池



5.4 newSingleThreadExecutor


newSingleThreadExecutor创建一个单线程化的线程池,它只有一个线程,用仅有的一个线程来执行任务,保证所有的任务按照指定顺序(FIFO,LIFO,优先级)执行,所有的任务都保存在队列LinkedBlockingQueue中,等待唯一的单线程来执行任务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/529075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1.Spring的核心思想 —— IOC和DI

1. Spring是什么&#xff1f; 简单的说&#xff0c;Spring其实指的是Spring Framework&#xff08;Spring框架&#xff09;&#xff0c;是一个开源框架。 如果要用一句话概括&#xff1a;它是包含众多工具方法的IOC&#xff08;Inverse of Control控制反转&#xff09;容器。…

【THM】Net Sec Challenge(网络安全挑战)-初级渗透测试

介绍 使用此挑战来测试您对网络安全模块中获得的技能的掌握程度。此挑战中的所有问题都可以仅使用nmap、telnet和来解决hydra。 挑战问题 您可以使用Nmap、 Telnet 和Hydra回答以下问题。 2.1小于10000的最大开放端口号是多少? 8080 nmap -p- -T4 10.10.234.218 2.2普通…

Java入门-java的方法

java方法 java的方法是用来完成某种功能的代码块。使用方法封装代码块&#xff0c;可以提高代码的可复用性&#xff0c;模块化&#xff0c;使用者无需知道代码的具体实现也能通过方法调用使用其提供的功能&#xff0c;简化了应用过程。 方法结构 一般一个方法的构成有如图几部…

【C++】vector问题解决(非法的间接寻址,迭代器失效 , memcpy拷贝问题)

送给大家一句话&#xff1a; 世界在旋转&#xff0c;我们跌跌撞撞前进&#xff0c;这就够了 —— 阿贝尔 加缪 vector问题解决 1 前言2 迭代器区间拷贝3 迭代器失效问题4 memcpy拷贝问题 1 前言 我们之前实现了手搓vector&#xff0c;但是当时依然有些问题没有解决&#xff…

HarmonyOS 开发-多模态页面转场动效实现案例

介绍 本示例介绍多模态页面转场动效实现&#xff1a;通过半模态转场实现半模态登录界面&#xff0c;通过配置NavDestinationMode类型为DIALOG&#xff0c;实现半模态的背景为透明&#xff0c;再与 全屏模态和组件转场结合实现多模态组合登录场景&#xff0c;其中手机验证码登录…

基于springboot+vue+Mysql的学习平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【Web】CTFSHOW-2023CISCN国赛初赛刷题记录(全)

目录 Unzip BackendService go_session deserbug 主打一个精简 Unzip 进来先是一个文件上传界面 右键查看源码&#xff0c;actionupload.php 直接访问/upload.php&#xff0c;看到后端的源码 就是上传一个压缩包&#xff0c;对其进行解包处理 因为其是在/tmp下执行…

ip地址切换器安卓版,保护隐私,自由上网

在移动互联网时代&#xff0c;随着智能手机和平板电脑的普及&#xff0c;移动设备的网络连接变得愈发重要。为了满足用户在不同网络环境下的需求&#xff0c;IP地址切换器安卓版应运而生。本文将以虎观代理为例&#xff0c;为您详细解析IP地址切换器安卓版的功能、应用以及其所…

机器学习 基础 笔记 1

train阶段就是正常的学习 validation是知道正确答案是啥&#xff0c;检查正确率 test是不知道正确答案是啥&#xff0c;看看有啥结果 训练的时候记得model.train 测试&#xff08;后面两种都是&#xff09;的时候要model.eval &#xff08;有些模型两种阶段做的事不一样&a…

不要抱怨,不如抱 Java 运算符吧 (下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人能接…

2024.4.9-day12-CSS 常用样式属性和字体图标

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 作业 作业 <!DOCTYPE html> <html lang"zh-CN"><he…

P4552 IncDec Sequence(差分)

题目描述 给定一个长度为 n n n 的数列 a 1 , a 2 , ⋯ , a n {a_1,a_2,\cdots,a_n} a1​,a2​,⋯,an​&#xff0c;每次可以选择一个区间 [ l , r ] [l,r] [l,r]&#xff0c;使这个区间内的数都加 1 1 1 或者都减 1 1 1。 请问至少需要多少次操作才能使数列中的所有数都…

rapidssl通配符证书760元

RapidSSL是Geotrust旗下的子品牌&#xff0c;旗下有两款基础型的数字证书产品——基础型单域名SSL证书和基础型通配符SSL证书。RapidSSL旗下的数字证书产品可以为个人或者企事业单位网站提供先进的加密算法和技术&#xff0c;确保网站数据在传输过程中不被窃取或篡改。今天就随…

Matlab|电价型负荷需求响应(考虑电价变化)

程序复现来源于《计及需求响应消纳风电的电-热综合能源系统经济调度 》第四章内容。 一、原理 需求响应的基本原理是需求侧根据电力市场价格和电网要求改变其负荷需求以 获取一定的利益回报。其中 PDR 可通过直观的电价变化信号引导用户调节用电方式&#xff0c; 从而达到优…

android11 如何修改状态栏的背景

修改status_bar.xml &#xff1a; <LinearLayout android:id"id/status_bar_contents"android:background"#1ABC9C"android:layout_width"match_parent"android:layout_height"match_parent"android:paddingStart"dimen/statu…

Linux部署FTP服务器

文章目录 什么是FTP协议&#xff1f;Linux上部署FTP服务器安装FTP服务启动FTP服务编辑/etc/vsftpd.conf重新启动服务测试FTP服务 什么是FTP协议&#xff1f; FTP协议是一种基于TCP的文件传输协议&#xff0c;能够实现高效的文件上传和下载功能&#xff0c;最重要的是它能够使用…

【群智能算法改进】一种改进的鹦鹉优化算法 鹦鹉优化器 IPO算法【Matlab代码#73】

文章目录 【获取资源请见文章第5节&#xff1a;资源获取】1. 原始鹦鹉优化算法PO2. 改进后的IPO算法2.1 自适应切换因子2.2 混合柯西和高斯变异 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节&#xff1a;资源获取】 1. 原始鹦鹉优化算法PO 鹦鹉优化算法…

【数据结构】:顺序表专题

前言&#xff1a;今天我们开始介绍数据结构有关内容&#xff0c;那么数据结构是什么呢&#xff1f; 数据结构是计算机存储、组织数据的方式。在工作中&#xff0c;我们通常会直接使用已经封装好的集合API(应用程序编程接口)&#xff0c;这样可以更高效地完成任务。但是作为一名…

构建高效网络:深入理解正向与反向代理的作用与配置

正向代理 如果把局域网外的互联网环境想象成一个巨大的资源库&#xff0c;则局域网中的客户端要访问互联网则需要通过代理服务器来访问&#xff0c;这种代理成为正向代理。 示例&#xff1a; 用户想要访问 https://chensir.ink &#xff08;目标服务器&#xff09;&#xff0…

【资源分享】这个网站我愿称之为年度学术最伟大的发现

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验&#xff0c;帮助大家尽早适应研究生生活&#xff0c;尽快了解科研的本质。祝一切顺利&#xff01;—…