问题标签 [executorservice]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java中的Future和FutureTask有什么区别?
既然 use ExecutorService
can submit
a Callable
task and return a Future
,为什么需要 use FutureTask
to wrap Callable
task and use the methodexecute
呢?我觉得他们都做同样的事情。
java - Java ExecutorService:等待终止所有递归创建的任务
我使用 anExecutorService
来执行任务。该任务可以递归地创建提交给相同的其他任务,ExecutorService
并且这些子任务也可以这样做。
我现在有一个问题,我想等到所有任务都完成(即所有任务都完成并且他们没有提交新任务)后再继续。
我无法调用ExecutorService.shutdown()
主线程,因为这会阻止新任务被ExecutorService
.
如果没有被调用,调用ExecutorService.awaitTermination()
似乎什么都不做。shutdown
所以我有点卡在这里。ExecutorService
看到所有工人都处于闲置状态并不是那么难,不是吗?我能想出的唯一不优雅的解决方案是直接使用 a并每隔一段时间ThreadPoolExecutor
查询一次。getPoolSize()
真的没有更好的方法吗?
java - 如何实现或找到线程安全的 CompletionService 的等价物?
我有一个在 Tomcat 容器内运行的简单 Web 服务,它本质上是多线程的。在进入服务的每个请求中,我想对外部服务进行并发调用。java.util.concurrent 中的 ExecutorCompletionService 让我部分获得了成功。我可以为它提供一个线程池,它会负责执行我的并发调用,并且当任何结果准备好时我会收到通知。
处理特定传入请求的代码可能如下所示:
这应该可以正常工作,但效率很低,因为正在为每个传入的请求分配一个新的线程池。如果我将 CompletionService 作为共享实例移出,我将遇到多个请求共享同一个 CompletionService 和线程池的线程安全问题。当请求提交任务并获得结果时,他们得到的结果并不是他们提交的结果。
因此,我需要的是一个线程安全的 CompletionService,它允许我在所有传入请求之间共享一个公共线程池。当每个线程完成一项任务时,应通知传入请求的相应线程,以便它可以收集结果。
实现这种功能最直接的方法是什么?我确信这种模式已经应用了很多次;我只是不确定这是否是 Java 并发库提供的东西,或者是否可以使用一些 Java 并发构建块轻松构建。
更新:我忘记提及的一个警告是,我希望在我提交的任何任务完成后立即收到通知。这是使用 CompletionService 的主要优势,因为它将任务和结果的生产和消费分离。我实际上并不关心我得到结果的顺序,我想避免在等待结果按顺序返回时不必要的阻塞。
java - 轻量级、可折叠的 Executor 实现?
我正在为 Android 构建一个移动应用程序,我需要为我的每个 List 适配器汇集 HTTP 请求。我基本上想要一个ExecutorService
“崩溃”的实现,即:它将使用多达n 个线程,但随着线程完成,它们将立即过期,使其非常轻量级。如果需求量很大,它只会将任务转储到等待线程可用的队列中。有没有办法在不写ExecutorService
自己的情况下做到这一点,或者我应该把手弄脏然后去做?
java - 使用计时器调度 Java 线程
我有一个 Runnable 类,它需要在上次运行后的设定间隔后运行。示例: ProcessThread 在完成后每 2 分钟运行一次。因此,如果我在 1:00 启动 ProcessThread,并且它需要 5 分钟(在 1:05 结束),那么下一次它应该运行将在 1:07。如果那个需要 3 分钟运行,(在 1:10 结束),下一个从 1:12 开始)等等..
我无法将其设置为 2 分钟的固定速率,因为这样会触发第二个线程,而第一个线程尚未完成。
所以,这是我当前的代码,但我拥有它的方式,它不断创建线程并且永远不会完成它们......所以最终我的记忆不断增长:
主要的:
ExecuteThread(我拿出了try-catch):
在我让调度程序在 MyProcessThread 中运行之前,但结果相同。这看起来是正确的方向,但仍然有问题。
java - 将 ExecutorService 与要执行的任务树一起使用
我们遇到了一点问题。:)
我们要确保任何时候只有 N 个线程在做后台任务。为此,我们使用了一个固定的线程池执行器。它似乎工作正常。
然后我们发现了一个问题。假设你有一个类,它使用 executor 来做一些并行工作,然后它在 executor 线程中调用其他一些类,它也做一些并行工作,打算等待它。这是发生的事情:
- 主线程调用第一级方法。
- 这种方法认为它可以并行化为 16 个任务并将其工作拆分。
- 16 个任务提交给执行者。
- 主线程开始等待其任务完成。
- 假设有四个线程可用,前四个任务每个都被拾取并运行。所以队列中还有 12 个任务。
- 现在,其中一项任务调用了其他方法。
- 这种新方法认为它可以并行化为 2 个任务。假设这是并行合并排序的第一步或类似的事情。
- 2个任务提交给执行者。
- 该线程现在开始等待其任务完成。
哦哦。所以在这一点上,所有四个线程现在都在等待任务完成,但它们正在协作阻止实际运行这些任务的执行程序。
此问题的解决方案 1 如下:在向执行程序提交新任务时,如果我们已经在运行所有线程,并且我们已经在其中一个执行程序线程上运行,则内联运行任务。这工作了 10 个月,但现在我们遇到了问题。如果它正在提交的新任务仍然相对较大,那么您可能会遇到新任务阻止该方法将其他任务添加到队列中的情况,否则这些任务将能够被其他工作线程拾取。因此,当线程在线处理工作时,您会遇到巨大的延迟。
对于执行潜在无界的后台任务树的核心问题,是否有更好的解决方案?我知道 .NET 相当于 executor 服务具有某种从队列中窃取的内置能力,可以防止发生原始死锁问题,据我所知,这是一个理想的解决方案。但是在 Java 的土地上呢?
java - 如何使用 CompletionService 取消耗时过长的任务
我使用围绕 2 线程 FixedThreadPool ExecutorService 包裹的 CompletionService 提交了一些 Future 任务,我设置然后设置一个等于提交的任务数量的循环,并使用 completionservice.take() 等待它们全部完成或失败。麻烦是偶尔它永远不会完成(但我不知道为什么)所以我将 take() 方法更改为 poll(300,Timeout.SECONDS),想法是如果一项任务需要超过 5 分钟才能完成poll 将失败,然后最终将退出循环,我可以遍历所有期货并调用 future.cancel(true) 以强制取消有问题的任务。
但是当我运行代码并且它挂起时,我看到轮询每 5 分钟连续失败一次并且没有更多任务运行,所以我假设这两个工作人员以某种方式陷入僵局并且永远不会完成,并且永远不允许启动其他任务。因为超时是 5 分钟,并且还有 1000 个任务要运行,所以打破循环所花费的时间太长,所以取消了作业。
所以我想要做的是中断/强制取消当前任务,如果没有在 5 分钟内完成,但我看不到任何方法。
此代码示例显示了我所说的简化版本
输出
java - 在 ExecutorService (Java/Clojure) 中休眠一个线程
我在 clojure 程序中创建了相当多的线程:
对我来说,JVM 之间已经有一段时间了,我基本上想知道这里是否有反对在 Executor 正在执行的函数中使用 sleep 或 yield 的论点?如果我理解正确,在这种情况下,我的每个工人都有自己的线程,因此应该没有副作用。
如果 Executor 使用的是 FixedThreadPool:
事情变得更加复杂,因为线程在工作完成之前不会返回到池中,这意味着如果线程处于睡眠状态,其他排队的工作人员将需要更长的时间才能完成。
在这种情况下,我对线程的理解是否正确?
(注意:我怀疑我的设计实际上是错误的,但只是想确保我在正确的页面上)
java - 多次成功执行线程后,Java 在循环中抛出 ExecutionException
我遇到了可调用线程的问题。
这是代码片段:
上面的代码会正确执行 18 次,然后在第 18 次之后抛出 ExecutionException。
我究竟做错了什么?
谢谢!
java - 使用多线程构建文件数据时出现额外字节
我正在处理大型数据集,在构建模型后,我使用多线程(Java 中的整个项目),如下所示:
当我收到每个可调用的结果时,将其输出到文件中。此输出是否与初始 Callables 列表的生成顺序完全相同?尽管有些人先于其他人完成?似乎应该但不确定。
此外,我预计总共有 620 万字节将写入输出文件。但我得到了额外的 2000 字节(是的,免费)。这弄乱了我的提交,我认为这是因为一些并发问题。我在小型数据集上对此进行了测试,它似乎在那里工作正常(预期和接收到 264 个字节)。
我在 Executor 框架或 Futures 上做错了什么?