b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

forkjoinpool_forkjoinpool源码分析_forkjoinpool 例子(3)

电脑杂谈  发布时间:2017-04-10 14:31:07  来源:网络整理

所以,线程池会有机制来限制列表/队列中任务的数量。但是,和设置最大线程数一样,并没有一个放之四海而皆准的最优任务数量。这还是要取决于具体的任务类型和不断的进行性能测试。

对于ThreadPoolExecutor而言,当任务数量达到最大时,再尝试增加新的任务就会失败。ThreadPoolExecutor有一个rejectedExecution方法用来拒绝该任务。这会导致应用服务器返回一个HTTP状态码500,当然这种信息最好以更友好的方式传达给Client,比如解释一下为什么你的请求被拒绝了。

定制ThreadPoolExecutor

线程池在同时满足以下三个条件时,就会创建一个新的线程:

有任务需要被执行

当前线程池中所有的线程都处于工作状态

当前线程池的线程数没有达到最大线程数

至于线程池会如何创建这个新的线程,则是根据任务队列的种类:

任务队列是 SynchronousQueue 这个队列的特点是,它并不能放置任何任务在其队列中,当有任务被提交时,使用SynchronousQueue的线程池会立即为该任务创建一个线程(如果线程数量没有达到最大时,如果达到了最大,那么该任务会被拒绝)。这种队列适合于当任务数量较小时采用。forkjoinpool也就是说,在使用这种队列时,未被执行的任务没有一个容器来暂时储存。

任务队列是 无限队列(Unbound Queue) 限的队列可以是诸如LinkedBlockingQueue这种类型,在这种情况下,任何被提交的任务都不会被拒绝。但是线程池会忽略最大线程数这一参数,意味着线程池的最大线程数就变成了设置的最小线程数。所以在使用这种队列时,通常会将最大线程数设置的和最小线程数相等。这就相当于使用了一个固定了线程数量的线程池。

任务队列是 有限队列(Bounded Queue) 当使用的队列是诸如ArrayBlockingQueue这种有限队列的时候,来决定什么时候创建新线程的算法就相对复杂一些了。比如,最小线程数是4,最大线程数是8,任务队列最多能够容纳10个任务。在这种情况下,当任务逐渐被添加到队列中,直到队列被占满(10个任务),此时线程池中的工作线程仍然只有4个,即最小线程数。只有当仍然有任务希望被放置到队列中的时候,线程池才会新创建一个线程并从队列头部拿走一个任务,以腾出位置来容纳这个最新被提交的任务。

关于如何定制ThreadPoolExecutor,遵循KISS原则(Keep It Simple, Stupid)就好了。比如将最大线程数和最小线程数设置的相等,然后根据情况选择有限队列或者无限队列。

总结

线程池是对象池的一个有用的例子,它能够节省在创建它们时候的资源开销。并且线程池对系统中的线程数量也起到了很好的限制作用。

线程池中的线程数量必须仔细的设置,否则冒然增加线程数量只会带来性能的下降。

在定制ThreadPoolExecutor时,遵循KISS原则,通常情况下会提供最好的性能。

ForkJoinPool

在Java 7中引入了一种新的线程池:ForkJoinPool。

它同ThreadPoolExecutor一样,也实现了Executor和ExecutorService接口。它使用了一个无限队列来保存需要执行的任务,而线程的数量则是通过构造函数传入,如果没有向构造函数中传入希望的线程数量,那么当前计算机可用的CPU数量会被设置为线程数量作为默认。

ForkJoinPool主要用来使用分治法(Divide-and-Conquer Algorithm)来解决问题。典型的应用比如快速排序算法。这里的要点在于,ForkJoinPool需要使用相对少的线程来处理大量的任务。比如要对1000万个数据进行排序,那么会将这个任务分割成两个500万的排序任务和一个针对这两组500万数据的合并任务。以此类推,对于500万的数据也会做出同样的分割处理,到最后会设置一个阈来规定当数据规模到多少时,停止这样的分割处理。比如,当元素的数量小于10时,会停止分割,转而使用插入排序对它们进行排序。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-40527-3.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    每日福利
    热点图片
    拼命载入中...