- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java并发编程面试之线程池由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
是一种基于池化思想管理线程的工具。池化技术:池化技术简单点来说,就是提前保存大量的资源,以备不时之需。比如我们的对象池,数据库连接池等.
。
我们为什么要使用线程池,直接new thread start不好吗?
。
我们先来看看线程池的一个执行流程图,此图来自文末参考1 。
通过上述图我们可以得出线程池执行任务可以有以下几种情况:
。
在java jdk的Executors有提供创建不同线程池的方法(一般不推荐这种做法)阿里巴巴的开发手册也明确强制规定不让通过Executors来创建的,在一些公司的开发规范里面应该也会有这么一条吧.
newFixedThreadPool 。
newSingleThreadExecutor 。
newCachedThreadPool 。
newScheduledThreadPool 。
newWorkStealingPool (jdk1.8新增的) 我们可以使用ThreadPoolExecutor来创建线程池 。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueueworkQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
我们可以看出创建线程池有七个参数,而上述我们通过Executors工具类来创建的线程池就一两个参数,其他参数它都帮我们默认写死了,我们只有真正理解了这几个参数才能更好的去使用线程池。下面我们来看看这七个参数(线程池参数).
。
核心线程数(线程池的基本大小)当我们提交一个任务到线程池时就会创建一个线程来执行任务.当我们需要执行的任务数大于核心线程数了就不再创建, 如果我们调用了prestartAllCoreThreads()方法线程池就会为我们提前创建好所有的基本线程.
。
最大线程数:线程池允许创建的最大线程数。如果队列已经满了,且已创建的线程数小于最大线程数,则线程池就会创建新的线程来执行任务。这里有个小知识点,如果我们的队列是用的无界队列,这个参数是不会起作用的,因为我们的任务会一直往队列中加,队列永远不会满(内存允许的情况).
。
空闲线程最大生存时间。当前线程数大于核心线程数时,结束多余的空闲线程等待新任务的最长时间。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize.
但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;比如当前线程池中最大线程数(maximumPoolSize)为50,核心线程数(corePoolSize)为10,当前正在跑任务的线程数为30.然后是不是空出了20个线程没活干,所以这20个线程就要被消毁,有点卸磨杀驴的感觉.
如果剩下的30个线程干完活了也休息了keepAliveTime这么久,然后这30个线程里面也要被销毁20个,就保留个核心线程。如果设置了allowCoreThreadTimeOut等于true核心线程也会被销毁。就跟我们做外包项目一样,甲方项目完成了就得去另外一个甲方,如果短时间内都没有甲方接纳你的话,你就要被辞退了,只会留下几个核心人员维护下项目,如果甲方项目维护的话用自己的人的话,所有的外包人会都会被辞退.
。
线程存活时间的的单位。可选的单位有days、hours等.
。
任务队列。可以选择以下这些队列 。
。
用户设置创建线程的工厂,我们可以通过这个工厂来创建有业务意义的线程名字。我们可以对比下自定义的线程工厂和默认的线程工厂创建的名字.
默认产生线程的名字 自定义线程工厂产生名字 。
pool-5-thread-1 testPool-1-thread-1 。
阿里开发手册也有明确说到,需要指定有意义的线程名字.
。
线程池拒绝策略。当队列和线程池都满了说明线程池已经处于饱和状态。必须要采取一定的策略来处理新提交的任务。jdk默认提供了四种拒绝策略:
其实我们也可以自定义任务拒绝策略(实现下RejectedExecutionHandler接口),比如说如果任务拒绝了我们可以记录下日志,或者重试等,根据自己的业务需求来实现.
dubbo 任务拒绝策略 。
@Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { String msg = String.format("Thread pool is EXHAUSTED!" + " Thread Name: %s, Pool Size: %d (active: %d, core: %d, max: %d, largest: %d), Task: %d (completed: " + "%d)," + " Executor status:(isShutdown:%s, isTerminated:%s, isTerminating:%s), in %s://%s:%d!", threadName, e.getPoolSize(), e.getActiveCount(), e.getCorePoolSize(), e.getMaximumPoolSize(), e.getLargestPoolSize(), e.getTaskCount(), e.getCompletedTaskCount(), e.isShutdown(), e.isTerminated(), e.isTerminating(), url.getProtocol(), url.getIp(), url.getPort()); logger.warn(msg); dumpJStack(); dispatchThreadPoolExhaustedEvent(msg); throw new RejectedExecutionException(msg); }//加入Java开发交流君样:756584822一起吹水聊天
我们可以看出dubbo的拒绝策略主要记录了详细的级别为warm的日志、输出当前线程堆栈详情、继续抛出拒绝任务异常.
。
线程池既然有这么多参数那么我们如何去根据自己的业务实际情况来去合理的设置每个参数?
如果既有IO密集型任务,又有CPU密集型任务,这种该怎么设置线程大小?这种的话最好分开用线程池处理,IO密集的用IO密集型线程池处理,CPU密集型的用cpu密集型处理。以上都只是理算情况下的估算而已,真正的合理参数还是需要看看实际生产运行的效果来合理的调整的.
。
线程池工作是否饱和?线程的情况如何?总共执行了多少个任务?现在线程池的运行情况如何?队列里面是否有堆积任务?面对上面这些问题,线程池也有提供一些方法可以让我们来查看上面这些指标.
有了这些参数我们是不是调整线程池的参数就更加方便了。或者根据线程池的活跃程度我们自动来调节(动态调整下篇再来说)线程池的参数.
关于线程池的几个问题 。
线程池是否区分核心线程和非核心线程?
如何保证核心线程不被销毁?
线程池的线程是如何做到复用的?
。
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我的更多内容! 。
原文链接:https://blog.csdn.net/wj1314250/article/details/117046413 。
最后此篇关于Java并发编程面试之线程池的文章就讲到这里了,如果你想了解更多关于Java并发编程面试之线程池的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试在多线程环境中实现某种累积逻辑;我想知道没有 lock 和 synchronized 关键字是否有更好/更快的方法来做到这一点?以下是我当前的代码: public class Concurr
我需要帮助构建一个实现信号量的监视器,简单的 C 示例就可以。 这是为了证明可以在任何可以使用信号量的地方使用监视器。 最佳答案 如果您说允许使用互斥锁/condvars,请检查: #include
我已经构建了一些返回部分产品目录的 ajax,并且我正在尝试将 xml 输出到文档中,到目前为止,这是我所拥有的: $("#catalog").append("Item NamePriceDe
很抱歉,如果我的问题之前已经被问过,或者它太明显了,但我真的需要澄清这一点。感谢您的帮助。 在多用户界面中,如果来自不同用户的相同事务同时到达服务器,会发生什么? 我有下一张表: create tab
这可能是一个愚蠢的问题,但是这个程序的输出(它的方式)可以为零吗? public class Test2{ int a = 0; AtomicInteger b = new Atomi
假设我本地主机上的一个网站处理每个请求大约需要 3 秒。这很好,正如预期的那样(因为它在幕后进行了一些奇特的网络)。 但是,如果我在选项卡(在 firefox 中)中打开相同的 url,然后同时重新加
我对 MongoDB 的读锁定有点困惑。单个集合可以支持多少个并发读取操作? 最佳答案 如 tk 给出的链接中所写:http://www.mongodb.org/pages/viewpage.acti
如果有四个并发的 CUDA 应用程序在一个 GPU 中竞争资源会发生什么这样他们就可以将工作卸载到图形卡上了? Cuda Programming Guide 3.1 提到那里 某些方法是异步的: 内核
👊上次的百度面试遇到了关于spark的并发数的问题,今天我们就来将这些问题都一并解决一下,图画的的有点丑,还行大家见谅,百度实习的问题我放在了下面的链接👇: 链接: 2022百度大数据开发工程师实
我对 Groovy 线程有疑问。 我的任务是以某种方式翻译给定目录中的每个文件 并将生成的输出放在其他目录中的文件中。 我编写了以下代码,该代码有效: static def translateDir(
Java中的同步和锁定有什么区别? 最佳答案 synchronized是语言关键字;锁是对象。 当一个方法或代码块被标记为同步时,您是说该方法或代码块必须先获得某个锁对象(可以在同步的语法中指定)才能
我需要创建一个能够同时处理来自客户端的多个请求的并发 RPC 服务器。 使用 rpcgen linux编译器(基于sun RPC),不支持-A为并发服务器创建 stub 的选项。 (-A 选项在 so
System.out.println("Enter the number of what you would like to do"); System.out.println("1 = Manuall
我正在将我的应用程序移植到 iOS 8.0 并注意到 UIAlertView 已被弃用。 所以我改变了使用 UIAlertController 的方法。这在大多数情况下都有效。 除了,当我的应用程序打
我正在逐行同时读取两个文本文件。 我特别想做的是当lineCount在每个线程上都是相同的我想看看扫描仪当前正在读取的字符串。 我环顾四周寻找可以实现的某些模式,例如 Compare and Swap
我正在阅读 Java Concurrency in Practice .在章节中断政策部分 取消和关闭 它提到 A task should not assume anything about the
我正在尝试学习线程,互斥等的基础知识。遵循here的文档和示例。在下面的代码中,我得到预期的输出。问题: 想确认我是否有任何陷阱?我们如何改善下面的代码? 我的线程在哪一行尝试获取互斥锁或正在等待互斥
并发是指两个任务在不同的线程上并行运行。但是,异步方法并行运行,但在同一个线程上。这是如何实现的?另外,并行性怎么样? 这三个概念有什么区别? 最佳答案 并发和并行实际上与您正确推测的原理相同,两者都
以此ConcurrentDouble类定义为例: public class ConcurrentDouble { public double num = 0; public void subt
在得知并发确实增加了许多人的吞吐量后,我一直计划在项目中使用并发。现在我在多线程或并发方面还没有做太多工作,因此决定在实际项目中使用它之前学习并进行简单的概念验证。 以下是我尝试过的两个示例: 1.
我是一名优秀的程序员,十分优秀!