Scala中Future的线程数

【博客搬迁】更好的格式显示,请访问新地址:http://josephguan.github.io/2016/06/26/thread-in-future/

  

 

为什么Future最大只有4个并发线程?

线程池中有多少个线程是由ExecutionContext决定的。如果使用的是默认的global,则只有4个并发线程。

import scala.concurrent.ExecutionContext.Implicits.global

 

默认的global ExecutionContext在哪里设置的4个并发线程?

global用的是ExecutionContextImpl,其中有这么一段代码:

 
  1. def createExecutorService: ExecutorService = {
  2.  
  3. def getInt(name: String, f: String => Int): Int =
  4. try f(System.getProperty(name)) catch { case e: Exception => Runtime.getRuntime.availableProcessors }
  5. def range(floor: Int, desired: Int, ceiling: Int): Int =
  6. if (ceiling < floor) range(ceiling, desired, floor) else scala.math.min(scala.math.max(desired, floor), ceiling)
  7.  
  8. val desiredParallelism = range(
  9. getInt("scala.concurrent.context.minThreads", _.toInt),
  10. getInt("scala.concurrent.context.numThreads", {
  11. case null | "" => Runtime.getRuntime.availableProcessors
  12. case s if s.charAt(0) == 'x' => (Runtime.getRuntime.availableProcessors * s.substring(1).toDouble).ceil.toInt
  13. case other => other.toInt
  14. }),
  15. getInt("scala.concurrent.context.maxThreads", _.toInt))
  16.  
  17. val threadFactory = new DefaultThreadFactory(daemonic = true)
  18.  
  19. try {
  20. new ForkJoinPool(
  21. desiredParallelism,
  22. threadFactory,
  23. uncaughtExceptionHandler,
  24. true) // Async all the way baby
  25. } catch {

庄家 ForkJoinPool 时设定了 desiredParallelism 。可以看到desiredParallelism函数得到并行度有多少是根据系统变量来的(注意getInt函数):

scala.concurrent.context.minThreads: 最小并发线程数(Int)

scala.concurrent.context.numThreads: 并发线程数,如果是Int,则就使用这个值;如果是String,并且以“x”开头,后面跟个Double(如“x1.5”),则其值为1.5 *  Runtime.getRuntime.availableProcessors

scala.concurrent.context.maxThreads: 最大并发线程数 (Int)

 

如果这三个变量没有设置,则getInt会取Runtime.getRuntime.availableProcessors,即当前CPU的核数。所以,在我的电脑上只有4个并发线程运行Future.

 

怎么改变Future的并发线程数?

1. 从上面的代码分析可以很容易想到,如果仍使用global ExecutionContext,修改系统变量即可:

 
  1. System.setProperty("scala.concurrent.context.minThreads", "8")
  2. System.setProperty("scala.concurrent.context.maxThreads", "8")

 

2. 更好的方法是重写一个自己的ExecutionContext。

 
  1. import java.util.concurrent.Executors
  2. import scala.concurrent._
  3.  
  4. implicit val ec = new ExecutionContext {
  5. val threadPool = Executors.newFixedThreadPool(1000);
  6.  
  7. def execute(runnable: Runnable) {
  8. threadPool.submit(runnable)
  9. }
  10.  
  11. def reportFailure(t: Throwable) {}
  12. }

 

 

 

 

 

 

 

 

来自为知笔记(Wiz)

 

转载于:https://my.oschina.net/guanxun/blog/482089

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值