1. ThreadPoolExecutor的一个常用的构造方法


ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) 

参数说明:

-corePoolSize       线程池中所保存的核心线程数。线程池启动后默认是空的,只有任务来临时才会创建线程以处理请求。prestartAllCoreThreads方法可以在线程池启动后即启动所有核心线程以等待任务。

-maximumPoolSize  线程池允许创建的最大线程数。当workQueue使用无界队列时(如:LinkedBlockingQueue),则此参数无效。

-keepAliveTime      当前线程池线程总数大于核心线程数时,终止多余的空闲线程的时间。

-unit          keepAliveTime参数的时间单位。

-workQueue       工作队列,如果当前线程池达到核心线程数时(corePoolSize),且当前所有线程都处于活动状态,则将新加入的任务放到此队列中。下面仅列几个常用的:

  • ArrayBlockingQueue:  基于数组结构的有界队列,此队列按FIFO原则对任务进行排序。如果队列满了还有任务进来,则调用拒绝策略。
  • LinkedBlockingQueue:  基于链表结构的无界队列,此队列按FIFO原则对任务进行排序。因为它是无界的,根本不会满,所以采用此队列后线程池将忽略拒绝策略(handler)参数;同时还将忽略最大线程数(maximumPoolSize)等参数
  • SynchronousQueue:   直接将任务提交给线程而不是将它加入到队列,实际上此队列是空的。每个插入的操作必须等到另一个调用移除的操作;如果新任务来了线程池没有任何可用线程处理的话,则调用拒绝策略。其实要是把maximumPoolSize设置成无界(Integer.MAX_VALUE)的,加上SynchronousQueue队列,就等同于Executors.newCachedThreadPool()。
  • PriorityBlockingQueue: 具有优先级的队列的有界队列,可以自定义优先级;默认是按自然排序,可能很多场合并不合适。

-handler          拒绝策略,当线程池与workQueue队列都满了的情况下,对新加任务采取的策略。

  • AbortPolicy:           拒绝任务,抛出RejectedExecutionException异常。默认值。
  • CallerRunsPolicy:   A handler for rejected tasks that runs the rejected task directly in the calling thread of the execute method, unless the executor has been shut down, in which case the task is discarded(没太弄懂意思,看不太懂,程序模拟半天也没得出啥结论。)
  • DiscardOldestPolicy:  如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程)。这样的结果是最后加入的任务反而有可能被执行到,先前加入的都被抛弃了。
  • DiscardPolicy:      加不进的任务都被抛弃了,同时没有异常抛出

2. 详解及示范

  1. 一个任务进来(Runnable)时,如果核心线程数(corePoolSize未达到,则直接创建线程处理该任务;如果核心线程数已经达到则该任务进入工作队列(workQueue)。如果工作队列满了(只能是有界队列),则检查最大线程数(maximumPoolSize是否达到,如果没达到则创建线程处理任务(FIFO);如果最大线程数据也达到了,则调用拒绝策略(handler)。
  2. 如果workQueue使用LinkedBlockingQueue队列,因为它是无界的,队列永远不会满,所以maximumPoolSize参数是没有意义的,同样keepAliveTimeunithandler三个参数都无意义。
  3. 如果workQueue使用ArrayBlockingQueue队列,那么小心,因为此队列是有界的,必须小心处理拒绝策略。你看人家Executors类,压根就不使用ArrayBlockingQueue队列。
  4. 正常情况下,如果使用Executors静态工厂生成的几种常用线程池能够满足要求,建议就用它们吧。自己控制所有细节挺不容易的。 
复制代码
package com.clzhang.sample.thread;import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class ThreadPoolTest3 {static class MyThread implements Runnable {private String name;public MyThread(String name) {this.name = name;}@Overridepublic void run() {// 做点事情try {Thread.sleep(1000);System.out.println(name + " finished job!") ;} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {// 创建线程池,为了更好的明白运行流程,增加了一些额外的代码
//        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(2);BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
//        BlockingQueue<Runnable> queue = new PriorityBlockingQueue<Runnable>();
//        BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();// AbortPolicy/CallerRunsPolicy/DiscardOldestPolicy/DiscardPolicyThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 5, TimeUnit.SECONDS,queue, new ThreadPoolExecutor.AbortPolicy());// 向线程池里面扔任务for (int i = 0; i < 10; i++) {System.out.println("当前线程池大小[" + threadPool.getPoolSize() + "],当前队列大小[" + queue.size() + "]");threadPool.execute(new MyThread("Thread" + i));}// 关闭线程池
        threadPool.shutdown();}
}
复制代码

输出(采用LinkedBlockingQueue队列):

当前线程池大小[0],当前队列大小[0]
当前线程池大小[1],当前队列大小[0]
当前线程池大小[2],当前队列大小[0]
当前线程池大小[2],当前队列大小[1]
当前线程池大小[2],当前队列大小[2]
当前线程池大小[2],当前队列大小[3]
当前线程池大小[2],当前队列大小[4]
当前线程池大小[2],当前队列大小[5]
当前线程池大小[2],当前队列大小[6]
当前线程池大小[2],当前队列大小[7]
Thread1 finished job!
Thread0 finished job!
Thread3 finished job!
Thread2 finished job!
Thread4 finished job!
Thread5 finished job!
Thread6 finished job!
Thread7 finished job!
Thread8 finished job!
Thread9 finished job!

3. 回头看看Executors静态工厂方法生成线程池的源代码

Executors.newSingleThreadExecutor()

复制代码
    public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}
复制代码

Executors.newFixedThreadPool()

    public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}

Executors.newCachedThreadPool()

    public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}

通过上述代码可以发现,用Executors静态工厂生成的几种常用线程池,都可以向里面插入n多任务:要么workQueue是无界的,要么maximumPoolSize是无界的。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring boot 启动卡住_SpringBoot集成的44种启动器,你知道几种?

点击蓝字“程序员考拉”欢迎关注&#xff01;啥是应用启动器&#xff1f;SpringBoot集成了spring的很多模块&#xff0c;比如tomcat、redis等等。你用SpringBoot搭建项目&#xff0c;只需要在pom.xml引入相关的依赖&#xff0c;和在配置文件中简单的配置就可以使用相应模块了。…

junit 经典示例_JUnit4参数化和理论示例

junit 经典示例我始终依靠TestNG将参数传递给测试方法&#xff0c;以便为我的测试或套件提供一些灵活性。 但是&#xff0c;使用JUnit4可以实现相同的灵活性。 要使用它很简单&#xff1a; package com.marco.test;import java.util.Arrays;import java.util.Collection;imp…

Spring+Hibernate+Atomikos集成构建JTA的分布式事务--解决多数据源跨库事务

一、概念 分布式事务 分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。简言之&#xff0c;同时操作多个数据库保持事务的统一&#xff0c;达到跨库事务的效果。 JTA JTA&#xff0c;即Java Transaction API&a…

spring el表达式 if else_Spring 获取单例流程(二)

读完这篇文章你将会收获到Spring 中 prototype 类型的 bean 如何做循环依赖检测Spring 中 singleton 类型的 bean 如何做循环依赖检测前言继上一篇文章 Spring 获取单例流程(一) 我们这次继续往下分析一下后面的流程上一篇文章中我们说到&#xff0c;首先我们根据 name 找到其对…

Apache Spark RDD和Java流

几个月前&#xff0c;我很幸运地参加了一些使用Apache Spark的PoC&#xff08;概念验证&#xff09;。 在这里&#xff0c;我有机会使用弹性分布式数据集&#xff08;简称RDD &#xff09;&#xff0c;转换和操作。 几天后&#xff0c;我意识到虽然Apache Spark和JDK是非常不同…

用脚本js把结果转化为固定小数位的形式

function roundTo(base,precision) {var mMath.pow(10,precision);var aMath.round(base * m) / m;return a; } 例如&#xff1a;给定数字n6.3241712&#xff0c;则用roundTo&#xff08;n,0&#xff09;得4&#xff0c;用roundTo(n,7)得到6.3241712转载于:https://www.cnblogs…

存储过程详解

什么是存储过程&#xff1a;存储过程可以说是一个记录集吧&#xff0c;它是由一些T-SQL语句组成的代码块&#xff0c;这些T-SQL语句代码像一个方法一样实现一些功能&#xff08;对单表或多表的增删改查&#xff09;&#xff0c;然后再给这个代码块取一个名字&#xff0c;在用到…

gpu版tensorflow测试

测试程序&#xff1a; import tensorflow as tfwith tf.Session(configtf.ConfigProto(allow_soft_placementTrue, log_device_placementFalse)) as sess:a tf.constant(1)b tf.constant(3)c a bprint(结果是&#xff1a;%d\n 值为&#xff1a;%d % (sess.run(c), sess.ru…

随机森林原理_机器学习(29):随机森林调参实战(信用卡欺诈预测)

点击“机器学习研习社”&#xff0c;“置顶”公众号重磅干货&#xff0c;第一时间送达回复【大礼包】送你机器学习资料与笔记回顾推荐收藏>机器学习文章集合&#xff1a;1-20机器学习(21): Tensorflow Keras手写数字识别机器学习(22): Tensorflow Keras识别猫狗机器学习(23)…

sudo 命令报错的解决方法

尝试着用终端打开Mac的安全权限&#xff08;sudo spctl --master-disable&#xff09;&#xff0c;却显示以下提示&#xff0c;望高手解答。sudo: /etc/sudoers is world writablesudo: no valid sudoers sources found, quittingsudo: unable to initialize policy plugin 解决…

BGR转RGB

原图&#xff1a; 源代码&#xff1a; #codingutf-8#OpenCV读进来的图像,通道顺序为BGR&#xff0c; 而matplotlib的顺序为RGB&#xff0c;因此需要转换 import cv2 import numpy as np from matplotlib import pyplot as pltimg cv2.imread(./test1.jpg) B, G, R cv2.split…

C++ set的一些用法

set也是STL中比较常见的容器。set集合容器实现了红黑树的平衡二叉检索树的数据结构&#xff0c;它会自动调整二叉树的排列&#xff0c;把元素放到适当的位置。set容器所包含的元素的值是唯一的&#xff0c;集合中的元素按一定的顺序排列。 我们构造set集合的目的是为了快速的检…

ide在控制台输入编译命令_快速编译调试 Redis

一&#xff1a;开篇Redis 它是个宝&#xff0c;男女老少都说好。秒杀限流分布式&#xff0c;什么需求都能搞。Redis 主要的用途是分布式缓存&#xff0c;其实不用我多介绍&#xff0c;相信大家都用过Redis。之前也看过不少Redis的书&#xff0c;其中就包括《Redis设计与实现》。…

Java增强枚举的用例

Brian Goetz在消息“ 增强枚举-用例 ”中写道&#xff1a;“我们希望就现在实现的功能[ 增强枚举 ]获得用户反馈。” 他陈述了他的信息的第一个目的&#xff1a;“开始工作&#xff0c;这是一些通用枚举可能有用的典型用例。” 所提供的两个示例中的第一个示例是重构com.sun.to…

图片上传获取名字

Override public ResultResponse<String> uploadImg(MultipartFile file) { String imgUrl null; try { //MultipartFile类中两个方法区别&#xff1a;//getName : 获取表单中文件组件的名字//getOriginalFilename : 获取上传文件的原名 String name file.getOriginalF…

tf.nn.softmax

通过Softmax回归&#xff0c;将logistic的预测二分类的概率的问题推广到了n分类的概率的问题。通过公式 可以看出当月分类的个数变为2时&#xff0c;Softmax回归又退化为logistic回归问题。 下面的几行代码说明一下用法 # -*- coding: utf-8 -*- import tensorflow as tfA […

python easygui_python简单图形界面GUI入门——easygui

首先是easygui包下载&#xff0c;两种方式&#xff1a;1)在命令行提示符环境下&#xff0c;用pip install easygui直接安装&#xff1a;2)从http://easygui.sourceforge.net下载。将下载得到的easygui.py文件&#xff0c;复制到Python安装路 径下的Lib文件夹中。等待安装完成即…

使用 Python ElementTree 生成 xml

Python 处理 xml 文档的方法有很多&#xff0c;除了经典的 sax 和 dom 之外&#xff0c;还有一个 ElementTree。 首先 import 之&#xff1a; 1from xml.etree import ElementTree as etree然后开始构建 xml 树&#xff1a; 1234567891011121314from xml.etree.ElementTree imp…

卷积核输出维度计算

1&#xff09;卷积层&#xff1a; 参数&#xff1a;W&#xff1a;宽&#xff1b; H&#xff1a;高&#xff1b; D&#xff1a;深度&#xff1b; K&#xff1a;卷积核的个数&#xff1b; F&#xff1a;卷积核的大小&#xff1b; S&#xff1a;步长&#xff1b; P&#xff1a;…

接受与返回json数据

转载于:https://www.cnblogs.com/classmethond/p/10801606.html