使用正确的 ExecutorService 异步执行任务
Using right ExecutorService to execute task asynchronously
在处理一项任务时,我必须处理 2 个子任务(基本上是步骤),这些子任务可以 异步完成。
我创建了 Executors.newSingleThreadExecutor() 并调用它执行了两次。由于它是单线程池,这是否意味着第二个子任务(即下面代码中的第 5 步)将连续执行,即仅在第 3 步完成后执行。我是否需要实例化 Executors.newFixedThreadExecutor(2) - 以 2 作为参数,因为我只需要异步执行两个步骤或者还应该执行其他操作。
public class MyTaskImpl
{
private static final ExecutorService JOB_EXEC_SVC = Executors.newSingleThreadExecutor();
public void doTask() throws Exception
{
// step 1
// step 2
// step 3 execute ASYNC
JOB_EXEC_SVC.execute(() -> step3(param1, param2));
// step 4
// step 5 execute ASYNC
JOB_EXEC_SVC.execute(() -> step5(param));
// step 6
}
}
你是对的。由于您正在使用的 ExecutorService
是使用 newSingleThreadExecutor
创建的,因此步骤 5 将在步骤 3 完成后完成。为了异步执行这两个动作,使用newFixedThreadExecutor
:
public class MyTaskImpl {
private static final ExecutorService JOB_EXEC_SVC = Executors.newFixedThreadExecutor(2);
public void doTask() throws Exception {
// Step 1
// Step 2
// Step 3 (below)
JOB_EXEC_SVC.execute(() -> step3(param1, param2));
// Step 4
// Step 5 (below)
JOB_EXEC_SVC.execute(() -> step5(param));
}
}
但这并不能保证第 3 步和第 5 步将并行执行。例如,如果第4步需要很长时间才能完成,则第5步可能会在第3步执行完毕后提交给ExecutorService
(即调用execute
)。
单线程情况下也是如此,但是无论第4步花费多少时间,第5步总是在第3步完成后执行(但不确定是否在第3步时提交第5步运行 并阻塞直到第 3 步完成,或者如果第 5 步在第 3 步完成后提交)。
你是对的。因为你使用单线程,所以那个线程是共享两个任务的。这意味着这两个任务将异步执行但它们将串行执行,即步骤 5 将在步骤 3 之后执行。如果您希望步骤 3 和步骤 5 同时执行,Executors.newFixedThreadExecutor(2) 对此很有用。您可以使用 Executors.newCachedThreadPool() 以获得更高的性能。
在处理一项任务时,我必须处理 2 个子任务(基本上是步骤),这些子任务可以 异步完成。
我创建了 Executors.newSingleThreadExecutor() 并调用它执行了两次。由于它是单线程池,这是否意味着第二个子任务(即下面代码中的第 5 步)将连续执行,即仅在第 3 步完成后执行。我是否需要实例化 Executors.newFixedThreadExecutor(2) - 以 2 作为参数,因为我只需要异步执行两个步骤或者还应该执行其他操作。
public class MyTaskImpl
{
private static final ExecutorService JOB_EXEC_SVC = Executors.newSingleThreadExecutor();
public void doTask() throws Exception
{
// step 1
// step 2
// step 3 execute ASYNC
JOB_EXEC_SVC.execute(() -> step3(param1, param2));
// step 4
// step 5 execute ASYNC
JOB_EXEC_SVC.execute(() -> step5(param));
// step 6
}
}
你是对的。由于您正在使用的 ExecutorService
是使用 newSingleThreadExecutor
创建的,因此步骤 5 将在步骤 3 完成后完成。为了异步执行这两个动作,使用newFixedThreadExecutor
:
public class MyTaskImpl {
private static final ExecutorService JOB_EXEC_SVC = Executors.newFixedThreadExecutor(2);
public void doTask() throws Exception {
// Step 1
// Step 2
// Step 3 (below)
JOB_EXEC_SVC.execute(() -> step3(param1, param2));
// Step 4
// Step 5 (below)
JOB_EXEC_SVC.execute(() -> step5(param));
}
}
但这并不能保证第 3 步和第 5 步将并行执行。例如,如果第4步需要很长时间才能完成,则第5步可能会在第3步执行完毕后提交给ExecutorService
(即调用execute
)。
单线程情况下也是如此,但是无论第4步花费多少时间,第5步总是在第3步完成后执行(但不确定是否在第3步时提交第5步运行 并阻塞直到第 3 步完成,或者如果第 5 步在第 3 步完成后提交)。
你是对的。因为你使用单线程,所以那个线程是共享两个任务的。这意味着这两个任务将异步执行但它们将串行执行,即步骤 5 将在步骤 3 之后执行。如果您希望步骤 3 和步骤 5 同时执行,Executors.newFixedThreadExecutor(2) 对此很有用。您可以使用 Executors.newCachedThreadPool() 以获得更高的性能。