我想通过一个方法将 Runnable 任务提交到 ForkJoinPool 中:
forkJoinPool.submit(Runnable task)
注意,我使用的是 JDK 7。
在底层,它们被转换为 ForkJoinTask 对象。 我知道 ForkJoinPool 在将任务递归拆分为较小的任务时非常有效。
问题:
如果没有递归,工作窃取在 ForkJoinPool 中是否仍然有效?
在这种情况下值得吗?
更新 1: 任务很小并且可能不平衡。即使对于严格相等的任务,诸如上下文切换、线程调度、停放、页面未命中等之类的事情也会阻碍导致不平衡。
更新 2: Doug Lea 在 Concurrency JSR-166 Interest 中写道组,通过给出提示:
This also greatly improves throughput when all tasks are async and submitted to the pool rather than forked, which becomes a reasonable way to structure actor frameworks, as well as many plain services that you might otherwise use ThreadPoolExecutor for.
我认为,当涉及到相当小的 CPU 密集型任务时,ForkJoinPool 是不错的选择,这要归功于这种优化。要点是这些任务已经很小,不需要递归分解。 Work-stealing 有效,无论是大任务还是小任务 - 任务都可以被另一个空闲的 Worker 从 Deque 的忙碌 Worker 的尾部中抢走。
更新 3: Scalability of ForkJoinPool - Akka 乒乓球队的基准测试显示了很好的结果。
尽管如此,为了更有效地应用 ForkJoinPool 需要进行性能调整。
最佳答案
ForkJoinPool 源代码有一个很好的部分,称为“实现概述”,请仔细阅读以获得终极真理。下面的解释是我对JDK 8u40的理解。
从第一天开始,ForkJoinPool 每个工作线程都有一个工作队列(我们称它们为“工作队列”)。 fork 的任务被插入本地工作队列,准备再次被工作人员弹出并执行——换句话说,从工作线程的角度来看,它看起来像一个堆栈。当一个 worker 耗尽它的 worker 队列时,它会四处走动并试图从其他 worker 队列中窃取任务。那就是“偷工减料”。
现在,在 (IIRC) JDK 7u12 之前,ForkJoinPool 有一个全局提交队列。当工作线程用完本地任务以及要窃取的任务时,他们会到达那里并尝试查看是否有外部工作可用。在这种设计中,与由 ArrayBlockingQueue 支持的常规 ThreadPoolExecutor 相比没有优势。
此后发生了显着变化。在此提交队列被确定为严重的性能瓶颈之后,Doug Lea 等人。也对提交队列进行了 strip 化。事后看来,这是一个显而易见的想法:您可以重用大多数可用于工作队列的机制。您甚至可以为每个工作线程松散地分配这些提交队列。现在,外部提交进入提交队列之一。然后,没有工作的工作人员可以先查看与特定工作人员相关的提交队列,然后四处寻找其他工作人员的提交队列。也可以称那为“偷工减料”。
我已经看到许多工作负载从中受益。 ForkJoinPool 的这种特殊设计优势即使对于普通的非递归任务也是很早以前就被认可的。 concurrency-interest@ 的许多用户要求一个简单的工作窃取执行器,而不需要所有的 ForkJoinPool 奥术。这是原因之一,为什么我们有 Executors.newWorkStealingPool()从 JDK 8 开始——目前委托(delegate)给 ForkJoinPool,但为了提供更简单的实现而开放。
关于具有非递归任务的 Java ForkJoinPool,工作窃取是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30047122/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo