简体   繁体   English

如何在 JAVA 中与执行程序服务并行调用相同的 function?

[英]How to call same function in parallel with executor service in JAVA?

I am new to concurrency and threading in java and I have this following scenario -我是 java 中的并发和线程新手,我有以下场景 -

Function1 (fetches next task from a queue and calls function2 with task) then Function2 (calls Function Run to run this task) then Run (function run is submiting task using executor service which has a fixed thread pool and code is like below) Function1 (从队列中获取下一个任务并使用任务调用 function2)然后Function2 (调用 Function Run 来运行此任务)然后Run (函数运行是使用具有固定线程池的执行器服务提交任务,代码如下所示)

ExecutorService exeService = Executors.newFixedThreadPool(3);
     private void run(Task task){
                Abstract batchExecutor = getBatchExecutor(param1,param2, param3, param4, task);
                Future<Void> future = exeService.submit(batchExecutor);
                while (!future.isDone()) {
                    if (isStopRequested.get()) {
                        try {
                            future.get(5, TimeUnit.MINUTES);
                            } catch (TimeoutException e) {
                        e.printStackTrace();
                    }
                    throw new InterruptedException("message");
                }
                        Thread.sleep(3000);
                }
                    future.get();
    }

My problem is even after declaring a thread pool also tasks are still running in sequential way.我的问题是即使在声明线程池之后,任务仍然以顺序方式运行。 How can I make it parallel so that as soon as there is another call to the run it should use free thread from pool and submit the task?我怎样才能让它并行,以便一旦有另一个运行调用它应该使用池中的空闲线程并提交任务?

There is no return type for all these functions.所有这些函数都没有返回类型。

The run(Task task) method contains future.get(); run(Task task)方法包含future.get(); at the end: this means that your current thread will block until the submitted operation is completed.最后:这意味着您当前的线程将阻塞,直到提交的操作完成。 Hence if you make 3x calls to run(Task task) in same thread then all 3 tasks will execute sequentially not in parallel.因此,如果您在同一线程中对run(Task task)进行 3 次调用,则所有 3 个任务将按顺序执行而不是并行执行。

How to handle this properly rather depends on how you structure your application.如何正确处理这取决于您如何构建应用程序。 If you don't submit huge number of tasks you could return the future from the method:如果您不提交大量任务,则可以从该方法返回未来:

private Future<Void> run(Runnable task){
    Abstract batchExecutor = getBatchExecutor(param1,param2, param3, param4, task);
    return exeService.submit(batchExecutor);
}

Then scan the results later:然后稍后扫描结果:

ArrayList<Future<Void>> pending = new ArrayList<>();
pending.add(run(task1));
pending.add(run(task2));
pending.add(run(task3));
// ...

// clean up background tasks
for (Future<?> fut : pending)
{
    fut.get();
}

Note that as you don't use results of the future, you can always omit the above loop over pending and just ensure that your app closes the executor queue after all tasks are completed:请注意,由于您不使用未来的结果,因此您始终可以省略上述pending的循环,并确保您的应用程序在所有任务完成后关闭执行程序队列:

exeService.shutdown();
exeService.awaitTermination(365, TimeUnit.DAYS);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM